š Automate NPM package publish & GIT versioning
Yair Even Or
Posted on January 20, 2021
Save time, improve your build process by streamlining releases.
Intro
Assuming a scenario for a typical package (which yourself is the sole author of), such as some sort of web component, CSS library, etc. which is intended to be used in a client and has some sort of a build process.
As mentioned above, this article is not meant for multi-developers codebase which are actively working on branches, because we don't want to tag anything when pushing, and certainly not publishing, since doing that is reserved for a dedicated pipeline (devops).
For the sake of example, this article presents a portion of code used in one of my packages - knobs, which is a pretty small project which uses Rollup to bundle the JS & SCSS.
š NPM scripts - basics
This topic has been addressed a lot and this article assumes basic knowledge of working with NPM custom scripts and with lifecycle ones, such as start
, test
, version
, prepublishOnly
and so on.
š„ What can go wrong without automatic release flow:
Since the project requires a build process, without automating the release flow as much as possible, unwanted outcome might occur:
- Accidentally deleted imported distribution file
- Forgetting to build before releasing
- Forgetting to tag the version
- Using wrong git tag (mismatch with
version
inpackage.json
- Not sure of the order of which things should be done before
publish
: should tag before committing or after? - Forgetting to push the tags
š¦ŗ Wanted: Something which guarantees nothing of above happens.
package.json
before the change:
{
"scripts": {
"start": "rollup -c rollup.config.dev.js -w",
"build:prod": "npm run clean && npm run bundle:prod",
"bundle:prod": "rollup -c rollup.config.prod.js",
"clean": "rm -rf knobs.min.js",
"test": "echo \"No test specified\"",
}
}
Pretty standard bunch of scripts, nothing interesting to talk about.
In order to publish the package, a non-automated release flow example would require to first run npm build:prod
, which will run the cleanup script and then the bundling script, which runs without the watch
command, because watching is unnecessary just before deploying since there is no code change. Then commit, and add a git tag and push with the tag, everything, and then publish the code. (or publish and then push).
Lets improve by adding a few scripts:
There are many ways to automate the above workflow (or half-automate), but I would like to talk about a specific tool which I find very helpful:
https://github.com/sindresorhus/np
-
np
is best installed globally:npm i -g np
-
headr
is a great package for automating header comment in the dist files, which includes information from thepackage.json
file itself, such as version, author name, repository url, etc. install it also if you wish. -
pkg-ok
is another script which ensures no (important) file is missing, I advise using it.
package.json
after the change š¤:
{
"scripts": {
"start": "rollup -c rollup.config.dev.js -w",
"build:prod": "npm run clean && npm run bundle:prod",
"bundle:prod": "rollup -c rollup.config.prod.js",
"clean": "rm -rf knobs.min.js",
"test": "echo \"No test specified\"",
"header": "headr knobs.min.js -o=knobs.min.js --version --homepage",
"version": "npm run build:prod && npm run header && git add .",
"prepublishOnly": "pkg-ok"
}
}
And the command used to publish & push is:
np --yolo
š§ Note that I am using the --yolo
flag because I want to skip tests (I don't have tests) and not clean the node_modules
and reinstall everything which can take long minutes.
np
package also allows writing a pre-defined configuration withinpackage.json
itself, using thenp
property.
version
(npm scripts property) is a lifecycle script hook which runs exactly at the appropriate time to build the code, output the bundle and add a header comment (to any file) with the just-bumped version number.
prepublishOnly
(npm scripts property) lifecycle hook is a good place to check no file is missing before proceeding, using pkg-ok
.
šāāļø Running the above command (np --yolo
) will present a GUI:
(screenshot from np
repo)
If all goes well, the package will be published and a new browser tab/window will open the project's GIT repository URL, for you to approve & publish a new tagged release in the repo.
Posted on January 20, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.