如何在package.json中指定所需的Node.js版本?

我有一个Node.js项目,需要Node版本12或更高。有没有办法在packages.json文件中指定这一点,以便安装程序自动检查并通知用户是否需要升级?

371208 次浏览

你可以在你的package.json中设置engines字段,并为nodenpm版本或两者设置要求:

  "engines" : {
"npm" : ">=8.0.0 <9.0.0",
"node" : ">=16.0.0 <17.0.0"
}

为了通过npm强制执行,你需要创建一个.npmrc文件(并将其提交到存储库),并将engines-strict选项设置为true,这将导致npm命令如npm install失败,如果所需的引擎版本不匹配:

# .npmrc
engine-strict=true

如果没有这个文件,每个开发人员都需要在他们的本地工作空间中运行npm config set engine-strict true来开启这个选项。

原来的答案

正如您所说的,您的代码肯定不能在任何低版本下工作,您可能需要“engineStrict"国旗:

{ "engineStrict" : true }

包的文档。json文件可以找到在NPMJS网站上

更新

engineStrict现在已弃用,所以这只会给出一个警告。现在,如果用户想要这个,就由他们来运行npm config set engine-strict true

更新2

正如ben在下面指出的,在项目的根目录创建.npmrc文件(与包的级别相同)。如果Node版本不兼容,则在安装过程中强制报错。

正如Ibam所说,engineStrict现在已弃用。但我找到了这个解决方案:

check-version.js:

import semver from 'semver';
import { engines } from './package';


const version = engines.node;
if (!semver.satisfies(process.version, version)) {
console.log(`Required node version ${version} not satisfied with current version ${process.version}.`);
process.exit(1);
}

package.json:

{
"name": "my package",
"engines": {
"node": ">=50.9" // intentionally so big version number
},
"scripts": {
"requirements-check": "babel-node check-version.js",
"postinstall": "npm run requirements-check"
}
}

在这里找到更多: # EYZ0 < / p >

< em > .nvmrc < / em >

还有一件事。 一个点文件。nvmrc'可用于要求特定的节点版本- https://github.com/creationix/nvm#nvmrc

但是,它只被npm脚本(和yarn脚本)尊重。

还有另一种更简单的方法:

  1. npm install Node@8(将Node 8保存为package.json中的依赖项)
  2. 你的应用程序将使用任何人的节点8运行——即使是Yarn用户!

这是因为node只是一个包,它将node作为它的包二进制文件发布。它只是包含node_module/.bin,这意味着它只使node对包脚本可用。不是主外壳。

推特上的讨论:https://twitter.com/housecor/status/962347301456015360

添加以下内容到package.json:

  "engines": {
"npm": ">=8.0.0 <9.0.0",
"node": ">=16.0.0 <17.0.0"
},

将以下内容添加到.npmrc(与package.json相同目录):

engine-strict=true

# EYZ0

如果你是像这样使用NVM,你可能应该这样做,那么你可以在git跟踪的.nvmrc文件中指出给定项目所需的nodejs版本:

node --version > .nvmrc

或者:

echo v10.15.1 > .nvmrc

这不会在cd上自动生效,这是正常的:用户必须执行以下操作:

nvm use

现在该版本的node将用于当前shell。

你可以列出你拥有的节点的版本:

nvm list

.nvmrc记录在:https://github.com/creationix/nvm/tree/02997b0753f66c9790c6016ed022ed2072c22603#nvmrc

如何自动选择节点版本在cd被问到:根据项目自动切换到正确的Node版本

用NVM 0.33.11测试。

.nvmrc vs package。json # EYZ1

你可能想做的是:

很像包装。Json vs package-lock.json。

赫鲁确实尊重包装。json # EYZ0

值得一提的是,作为记录在这里, Heroku确实很好地遵守了engines:条目,例如:

  "engines": {
"node": "14.17.0",
"npm": "6.14.13"
},

所以你应该永远,永远设置为你在本地使用的。

这在之前的自删除此线程的答案中已经提到过。

一个Mocha测试用例示例:

describe('Check version of node', function () {
it('Should test version assert', async function () {


var version = process.version;
var check = parseFloat(version.substr(1,version.length)) > 12.0;
console.log("version: "+version);
console.log("check: " +check);
assert.equal(check, true);
});});

下面是基于亚当的回答的完整的现成脚本。

# EYZ0:

/* eslint-disable no-console */
const fs = require('fs');
const semver = require('semver');
const childProcess = require('child_process');


// checks that current node and npm versions satisfies requirements in package.json
// to run manually:   node check-version.js [verbose]


const VERBOSE_FORCED = false;
const args = process.argv.slice(2);
const VERBOSE = VERBOSE_FORCED || (args.length > 0 && args[0] === 'verbose');


const printErrAndExit = (x) => {
console.error(x);
console.error('Aborting');
process.exit(1);
};


const checkNpmVersion = (npmVersionRequired) => {
if (!npmVersionRequired) {
console.log('No required npm version specified');
return;
}
const npmVersion = `${childProcess.execSync('npm -v')}`.trim();
if (VERBOSE) console.log(`npm required: '${npmVersionRequired}' - current: '${npmVersion}'`);
if (!semver.satisfies(npmVersion, npmVersionRequired)) {
printErrAndExit(`Required npm version '${npmVersionRequired}' not satisfied. Current: '${npmVersion}'.`);
}
};


const checkNodeVersion = (nodeVersionRequired) => {
if (!nodeVersionRequired) {
console.log('No required node version specified');
return;
}
const nodeVersion = process.version;
if (VERBOSE) console.log(`node required: '${nodeVersionRequired}' - current: '${nodeVersion}'`);
if (!semver.satisfies(nodeVersion, nodeVersionRequired)) {
printErrAndExit(`Required node version '${nodeVersionRequired}' not satisfied. Current: '${nodeVersion}'.`);
}
};


const json = JSON.parse(fs.readFileSync('./package.json'));
if (!json.engines) printErrAndExit('no engines entry in package json?');
checkNodeVersion(json.engines.node);
checkNpmVersion(json.engines.npm);

它应该放在根项目目录中。

它检查节点和/或npm版本,如package.json (engines条目)中指定的,例如

  "engines": {
"node": ">=16.0.0 <17.0.0",
"npm": ">=8.0.0 <9.0.0"
},

您可以手动调用它

# EYZ0

或者将它作为脚本包含在package json中,要么作为独立脚本,要么作为其他脚本的先决条件,例如

"scripts" : {
"start": "node check-version.js && vite",
"build": "node check-version.js && vite build",
"lint": "node check-version.js && eslint .",
"check-version": "node check-version.js verbose"
},