Update 23. April 2018: Starting from Angular CLI 1.7, there exists an official update command:
ng update. The approaches described below are not required anymore.
Managing your build environment on your own can be very hard. The Angular CLI can make your life easier in the Angular ecosystem, but its manual upgrade process leaves a lot to be desired. In this article I want to present two approaches to automating the dependency update process. My proposal is also valid for similar code generator tools in node.js.
The Angular CLI provides a pre-configured setup including boilerplate code generation, webpack and a package.json containing all required dependencies. Since it is directly from the Angular team itself, the Angular CLI sticks to best practices and is heavily maintained and extended.
Those updates happen regularly. The boilerplate code the Angular CLI generates, however, does not automatically update along with it. This is also true for the dependencies in package.json as well as files like those for Karma or TypeScript. Luckily they don’t change that often.
The typical upgrade process makes you globally upgrade the existing Angular CLI installation, create a new temporary project by calling “ng new (projectname)” and then apply the differences of the generated boilerplate files to your existing ones. This manual process takes time and is error-prone.
Approach 1: Yarn Workspaces
The easiest way to add additional dependencies would be to use the Workspaces feature of Yarn which exists to support mono-repositories.
A mono-repository consists of a root project that defines common dependencies and multiple projects that can depend on each other and share that common root. The term “mono” derives from the fact that they are all put into a single git repository.
We set our Angular CLI package.json as the root project and put a second package.json directly into the generated `src` subfolder. The second package.json will contain all our individual dependencies and the root one will stay untouched (more or less - see below).
- Ensure you have installed yarn with version 1.0 or later.
- Add a workspaces property to your package.json, that contains the value `[“src”]`.
- Create a new package.json directory “src” by running `npm init`.
- Add your dependencies in directory “./src” with `yarn add`.
- After yarn has installed the dependencies, make sure there is only a single yarn.lock in the root directory of your project.
The project is available on GitHub.
Approach 2: package-json-merge
Yarn Workspaces can only manage dependencies. If you have to alter other parts of the generated package.json, like adding a proxy flag to the executing start script, then you have to overwrite the original file again.
A very simply npm tool called package-json-merge can overcome this by merging two files and without using Workspaces. In contrast to the first approach, package-json-merge doesn’t contain any logic in terms of dependency management. That is why I rate it as a second approach.
- Rename the existing package.json to package.ng.json.
- Create a new package.json that will be our individual one with `npm init`.
- Install package-json-merge by running `npm install package-json-merge --save-dev`.
- Add the following key-value to the `scripts` property in package json: `merge-json: package-json-merge package.ng.json package.individual.json > package.json`.
- Copy the individual package.json to package.individual.json.
- Run `npm merge-json`.
The project is available on GitHub.
Neither solution is perfect. Still, they automate the update process and that makes them superior to the annoying manual process.
Angular is working on an update feature in one of their next versions of the CLI, so keep an eye on their announcements.