npm not being a build tool in itself (only handles dependencies and executes scripts), you may refer to unspecified build command and executable?
Our build pipeline is basically
npm ifollowed by some customnode script.jsthennpm test,npm prune,npm auditetc.
npm testjust executes yourscripts.testcommand; if the underlying executable requires Node, it will use the binary specified in thePATHnpm pruneandnpm auditwork on your dependencies and their version, irrespective of Nodenode script.jsobviously uses the corresponding Node version (here what is specified in thePATH)npm installwill install the package dependencies (and development dependencies), according to their specified versions; it is up to you to ensure compatibility of your dependencies version with your targeted Node version; if they specify some Node engines constraint, and the latter is not met by the version inPATH, it will only produce a warning (unless you set theengine-strictflag):
Unless the user has set the
engine-strictconfig flag, this field is advisory only and will only produce warnings when your package is installed as a dependency.
That being said, with nvm you can at least use a specific node and npm version, for a single command, irrespective of the current system, terminal session or default node/npm version of your build server, using nvm exec <nodeVersion> npm <command>:
you can run any arbitrary command in a subshell with the desired version of node
(Or its associated npm version)
For example:
nvm exec 18 npm install # Will use the appropriate npm version for Node v18, and will see that Node v18 if needing Node
It actually launches a subshell and nvm use <version> under the hood, and executes your command there. Therefore these Node and npm versions may differ from the rest of the machine shells.
For example if a dependency has a prepare script that requires Node, it will get the version provided by nvm exec <version> after being npm install'ed.
» npm install node
Videos
npm not being a build tool in itself (only handles dependencies and executes scripts), you may refer to unspecified build command and executable?
Our build pipeline is basically
npm ifollowed by some customnode script.jsthennpm test,npm prune,npm auditetc.
npm testjust executes yourscripts.testcommand; if the underlying executable requires Node, it will use the binary specified in thePATHnpm pruneandnpm auditwork on your dependencies and their version, irrespective of Nodenode script.jsobviously uses the corresponding Node version (here what is specified in thePATH)npm installwill install the package dependencies (and development dependencies), according to their specified versions; it is up to you to ensure compatibility of your dependencies version with your targeted Node version; if they specify some Node engines constraint, and the latter is not met by the version inPATH, it will only produce a warning (unless you set theengine-strictflag):
Unless the user has set the
engine-strictconfig flag, this field is advisory only and will only produce warnings when your package is installed as a dependency.
That being said, with nvm you can at least use a specific node and npm version, for a single command, irrespective of the current system, terminal session or default node/npm version of your build server, using nvm exec <nodeVersion> npm <command>:
you can run any arbitrary command in a subshell with the desired version of node
(Or its associated npm version)
For example:
nvm exec 18 npm install # Will use the appropriate npm version for Node v18, and will see that Node v18 if needing Node
It actually launches a subshell and nvm use <version> under the hood, and executes your command there. Therefore these Node and npm versions may differ from the rest of the machine shells.
For example if a dependency has a prepare script that requires Node, it will get the version provided by nvm exec <version> after being npm install'ed.
unfortunately nvm is not "CI Friendly" as it is not a binary on the $PATH but a command (bash function) which must be loaded for every step of the pipeline. I think what we are looking for is a way to run specific, synchronized version of npm, npx and node.
Besides performing each build in a dedicated Docker container, you may be interested in Volta:
Volta keeps track of which project (if any) you’re working on based on your current directory. The tools in your Volta toolchain automatically detect when you’re in a project that’s using a particular version of the tools, and take care of routing to the right version of the tools for you.
And:
Volta does not use any fancy OS features or shell-specific hooks.
Volta replaces the node, npm, npx (and potentially many more) binaries by shims, which enable it to route to the appropriate version, based on what is specified in the package.json file of the project the binary is invoked from.
E.g. in your "NodeJS v20 apps", you would have:
// package.json
{
"volta": {
"node": "20"
}
}
...and whenever node, npm or npx are called from within these project folders, they would use node 20 or the bundled version of npm and npx.
Without having to configure anything globally on your build machine for a particular build run or step.
Is it possible to specify that NPM should only install a package if Node version < 20? Specifically I want to install node-fetch only when I need it. This is for a package that will be used by multiple teams using whatever version they're using so I have no control over the version and I need to support 16+
» npm install npm