Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for upgrading npm `prepublish` script for npm@>=4

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.

like image 894
Burt_Harris Avatar asked May 18 '17 02:05

Burt_Harris


People also ask

What is prepublishOnly?

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).

How do I run a script after npm install?

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/.


1 Answers

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:

  1. Add a development dependency with npm install -D check-node-version@1,
  2. Rename the existing prepublish script to prepare,
  3. Add a replacement 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
like image 63
Burt_Harris Avatar answered Oct 19 '22 18:10

Burt_Harris