The npm community forum has been discontinued.
To discuss usage of npm, visit the GitHub Support Community.
How to enforce node version compatibility during local development only
Hello, me and my team are enforcing node versions during local development on a project by adding a node version range in the package.json
engines field and setting
true in a root-level
.npmrc file. This works great since running any
npm commands would fail with a helpful error when the developer is using a node version not specified in the
engines field. But I’ve noticed that it causes problems when the project with this setup becomes a dependency of another project. Take this example:
- Developer 1 has node version 12 installed on local machine
- Developer 1 creates repository for
foo-deppackage that has its
engines.nodefield set to
engine-strict=truein a root-level
.npmrcfile to enforce node version when working on the project locally
- Developer 1 publishes
- Developer 2 has node version 11 installed on local machine
- Developer 2 tries to run
npm i foo-deppackage on Project X with its own
The installation will fail for Developer 2 because the developer tried to install
foo-dep while using a node version that is incompatible with
foo-dep. I understand this error if the
What is the recommended way to ensure a node version is enforced when developing on the
foo-dep project, but is not enforced on developers who install it?
As documented, the engines field of package.json is used to specify the runtime requirements of a package. As such, its purpose is to ensure that a package is not installable (or at least warns of incompatibility) on node versions that are incompatible. The setup you describe above is working as designed to ensure that a package declared to only support node 12 is not installable on versions less than 12.
IOW, the engines field of package.json is not to be used for development version locking. That’s not its purpose or role, and attempting to use it as such leads to complications.
If your goal is to allow developers a way to lock their development environments to a particular version of node, without impacting the runtime requirements of a package, that is what node version managers are for. I suggest nodenv. Nodenv is built to lock either an application (development or production) or a package (development) to a particular version of node. With the nodenv-aliases plugin, you can provide loose version specifiers. And with the nodenv-package-json-engine plugin, nodenv will fall back to respecting the package.json#engines field when a .node-version file does not exist.
Thanks for the reply! The problem is that I work for a company with very very large, independently-operated teams. We have a ton of projects, that each require different local versions of node. We’ve found that simply adding node version disclaimers on READMEs or instructions to use certain binaries like node version managers are unsuccessful.
We’d like the ability to enforce a node version when working on a package locally that is not enforced at the consumer level for our client-side npm packages. How can we do this without relying on node version managers? We’d like to exit with an error code and helpful message whenever an npm command is run on a project while using an incompatible node version.
FYI I’ve also opened https://github.com/npm/rfcs/issues/50 to explore doing an RFC for this feature.