Reputation: 7225
When building an Angular Library application, is there an automated way to keep the root level package.json and the library application's package.json (e.g. under projects/my-library
) file versions in sync when using npm version
commands?
When I use the command, it's only incrementing the root level package.json, is there a special command, or any other way to propagate the version number down to the library package.json file?
I have seen some solutions such as running a script after ng build
to read the root level package.json version number and write that into the library one but I'm not sure this is the best approach.
Has anyone else faced this when building libraries in Angular and if so what was your way to deal with it?
Upvotes: 24
Views: 7913
Reputation: 2408
I made the following solution:
Flow:
create-tarball
should be executed right after the library has been build. it means when the ng build
was executed but automatically precreate-tarball
is going to be executed before.
Thencreate-tarball
will be executed.
Finally postcreate-tarball
will be executed automatically too.
Command explanation:
precreate-tarball
: Update the package version in the workspace paths (In my case is the demo application and the library distribution folder). This is because its better update the version right after the ng build be success.
create-tarball:
Build the pack for the distribution folder (tarball).
postcreate-tarball:
It keeps the demo or parent package.json and the library package json synchronized
{
"build":"ng build",
"postbuild": "npm run create-tarball"
"precreate-tarball": "npm version prerelease --workspaces=true --no-git-tag-version --force",
"create-tarball": "cd dist/my-library && npm pack",
"postcreate-tarball": "sync-json -v --property version --source package.json projects/my-library/package.json",
},
"workspaces": [
"./",
"dist/my-library"
],
You can install sync-json from npm
Upvotes: 0
Reputation: 732
npm 7 has support for workspaces.
In npm 7 you can use workspaces with npm version
You can add your workspaces to your package.json like this:
{
"name":"parent",
"workspaces":[
"projects/child-a",
"projects/child-b"
]
}
When using workspaces npm version will not create a commit or tag (there could be version name conflicts).
If you might want to add the changed files, commit them and create a tag automatically for each workspace you can use a version script.
"scripts": {
"version": "git add . && git commit -m \"Version $npm_package_version\" && git tag v$npm_package_version",
"postversion": "git push && git push --tags"
},
Keep in mind that tag names must be unique. You might want to prefix the name of the workspace to the tag.
And then run
npm version major --workspaces=true
Please note that Angular only supports the LTS version of node which may affect your ability to use workspaces in your build process.
Upvotes: 2
Reputation: 1495
I use a combination of sync-json and "pre-post version" scripts to help with this.
npm i -D sync-json
Here's what my package.json
looks like:
{
...,
"scripts": {
"build:lib": "ng build --prod my-lib",
"sync-version": "sync-json -v --property version --source package.json projects/my-lib/package.json",
"preversion": "rm -rf ./dist",
"version": "npm run sync-version && npm run build:lib && git add -A && git commit -m \"bump up\"",
"postversion": "git push && git push --tags"
},
...
}
Just for clarity:
Upvotes: 3
Reputation: 12750
For my Angular library, I was forced to bump the version in the project package.json
file, the child one not the parent workspace one. So I needed to update the version property in the parent workspace package.json
file.
├── package.json
└── projects
└── lib-pwa
└── package.json
For this I created in the ~/dev/commands/ng.sh
file the bash ng-version-sync-parent
command:
#!/bin/bash
ng-version-sync-parent() {
version=`find ./projects -name package.json -exec cat {} + | jq --raw-output '.version'`;
echo 'Project package version: '$version;
jq --arg version $version ".version = \"$version\"" package.json | sponge package.json
version=`cat package.json | jq --raw-output '.version'`;
echo 'Workspace package version: '$version;
}
I then used it in my workspace directory:
source ~/dev/commands/ng.sh
11:29 $ ng-version-sync-parent
Project package version: 0.1.4
Workspace package version: 0.1.4
Upvotes: 2
Reputation: 897
I've seen people ask the same question to vsavkin (Nrwl/Nx dude) and his response was a fairly involved git sub-module approach.
While this workflow is a little complex, it does allow shared libraries to be individually versioned whilst keeping them in the same parent git-repo.
A simpler alternative is, as you have already mentioned, to keep all libraries in a monorepo the same version as the root package.json - similar to how the Angular monorepo bumps its versions of all the Angular packages at the same time.
This can be done easily in node, or in bash/shell with a little bit more scripting.
To actually bump the versions of the packages here's a simple approach: install this npm package (a nice CLI for editing json files) and read the In-Place editing section. You should now have all the tools you need!
Here's an example bash script using node:
cd libs/my-library && json -I -f package.json this.version=$(node -pe \"JSON.stringify(require('../../package.json').version)\")
Upvotes: 11