I run npm install
from my sample project's root folder to build it using scripts in package.json
.
The build requires a few transpilation steps currently in the prepublish
script, but npm version 4 displays a warning that a breaking change is coming, leading me to believe the new prepare
build event script is more future proof.
C:\code\antlr4ts-json>npm install
npm WARN prepublish-on-install As of npm@5, `prepublish` scripts will run only for `npm publish`.
npm WARN prepublish-on-install (In npm@4 and previous versions, it also runs for `npm install`.)
npm WARN prepublish-on-install See the deprecation note in `npm help scripts` for more information.
...
Unfortunately, simply moving the script from prepublish
to prepare
breaks backward compatibility: If someone runs npm install
using npm@3
, the build steps in prepare
are silently ignored.
What's the best practice for upgrading my build-time script? Ideally, I'd like to update my package.json
so that npm install
works for any npm@>=3, but alternatively generating a clear error message indicating that npm@>=4 is required at when npm install
is run using npm@3 would be perfectly acceptable.
Bakground: I tried including
"engines": { "npm": ">=4.0.0" },
Thanks to @toomuchdesign (and others), I understand why this doesn't do what I want; engines
only checks when my package is installed as a dependency, not someone builds it from sources. That makes sense.
I tracked the background on this planned change down to npm issue #10074, which explains why a breaking change is needed. However I'm still unclear how to handle the transition better.
A new event, prepublishOnly has been added as a transitional strategy to allow users to avoid the confusing behavior of existing npm versions and only run on npm publish (for instance, running the tests one last time to ensure they're in good shape).
You can easily run scripts using npm by adding them to the "scripts" field in package. json and run them with npm run <script-name> . Run npm run to see available scripts. Binaries of locally install packages are made available in the PATH , so you can run them by name instead of pointing to node_modules/.
I found a better solution using check-node-version
; that package has a command line interface, making it easy to use for this purpose. Here are the steps I would propose as a best-practice:
npm install -D check-node-version@1
,prepublish
script to prepare
,prepublish
script to handle backward compatibility, and suggest upgrading npm (see below.)My package.json now looks something like this:
"scripts": {
"prepare": "npm run antlr4 && tsc",
"prepublish": "check-node-version --npm \">=4\" || npm run prepare",
"antlr4": "rimraf gen && antlr4ts Json.g4 -o gen -visitor",
...
},
"devDependencies": {
"check-node-version": "^1.1.2",
...
With this approach:
npm install
always runs the prepare
script, even with npm@3
installed. This should presumably work correctly if npm@5
is installed (untested.)
On npm@3
there's even a helpful message about upgrading npm, but because the script uses || npm run prepare
to simulate the behavior of later versions, the script continues after the error.
If I later want to take a hard dependency on npm@4
, removing the || npm run prepare
part would cause the script to stop if run on npm@3
.
Here's what a build looks like using npm@3
:
C:\code\antlr4ts-json>npm i
> [email protected] prepublish C:\code\antlr4ts-json
> check-node-version --npm ">=4" || npm run prepare
node: v6.9.1
npm: v3.10.10
Error: Wanted npm version ">=4" (>=4.0.0)
To install npm, run `npm install -g npm@>=4`
> [email protected] prepare C:\code\antlr4ts-json
> npm run antlr4 && tsc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With