ChatGPT解决这个技术问题 Extra ChatGPT

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

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

与 Adam 的响应类似的方式,也使用 node.version:stackoverflow.com/a/48691987/3032209
这里已经提出了问题:如何强制使用特定的 node.js 版本?
我想知道是否有任何工具可以通过检查 API 使用情况自动将此字段设置为适当的值。
注意:如果使用 yarn 版本 2+,您将需要安装此处找到的纱线引擎插件:github.com/devoto13/yarn-plugin-engines

d
dhilt

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

  "engines" : { 
    "npm" : ">=7.0.0",
    "node" : ">=16.0.0"
  }

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

# .npmrc
engine-strict=true

如果没有该文件,每个开发人员都需要在其本地工作区中运行 npm config set engine-strict true 才能打开此选项。

原始答案

正如您所说,您的代码绝对不适用于任何较低版本,您可能也需要“engineStrict”标志:

{ "engineStrict" : true }

可以找到 package.json 文件的文档 on the npmjs site

更新

engineStrict 现在已弃用,因此只会发出警告。现在由用户来运行 npm config set engine-strict true,如果他们想要的话。

更新 2

正如下面所指出的,如果 Node 版本不兼容,在项目的根目录(与 package.json 文件相同的级别)创建一个带有文本 engine-strict=true.npmrc 文件将在安装期间强制出错。


github.com/npm/npm/blob/master/CHANGELOG.md#enginestrict "很少使用的 package.json 选项 engineStrict弃用几个月,在使用时会产生警告。从 npm@3 开始,该字段的值被忽略,引擎违规只会产生警告。如果您作为用户,想要严格的引擎字段强制执行,只需运行 npm config set engine-strict true"
请记住 cd .. && npm i <folder-name> 以检查项目本身。但是,这将触发它自身的整个构建。
为什么他们在地球上弃用它..它失去了它的所有意义
现在将 engine-strict=true 添加到您的 .npmrc 具有相同的效果
@ben 完美,谢谢!这可以提交,以便至少您的整个团队都需要遵守引擎版本要求。
B
Bouke Versteegh

将以下内容添加到 package.json

  "engines": {
    "npm": ">=6.0.0",
    "node": ">=10.0.0"
  },

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

engine-strict=true

这是最简单的解决方案,它会在最终用户运行 npm install 时给最终用户一个关于没有正确版本的节点的很好的错误;也适用于 yarn
这似乎根本没有效果。我使用与上述类似的“引擎”部分(11.13.06.7.0)设置了我的 package.json,并设置了一个除了上面指定的内容之外什么都没有的 .npmrc。我让 nvm 将我切换到较旧的节点版本,然后运行 npm install,但它只是安装依赖项,甚至没有提及引擎版本不匹配。
engine-strict=true 添加到 your .npmrc 文件只会强制 youyou 安装软件包时使用正确的引擎。 它不会对您的最终用户强制执行任何操作。如果您希望您的用户在安装时使用 package.json 中 "engines: {}" 属性下列出的引擎,您应该告诉他们 engine-strict=true 添加到 他们的 .npmrc 文件。
@chharvey,您可以将脚本添加到 package.json "preinstall": "echo 'engine-strict=true' >> .npmrc"
direnv 的 .envrc github.com/direnv/direnv/wiki/Node 目前不支持 .npmrc 中的 engine-strict 用法(发现版本 engine-strict=trueN/A 的“.nvmrc”:版本“engine-strict=true -> N/A”是尚未安装。
A
Adam

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

检查-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);
}

包.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"
  }
}

在此处了解更多信息:https://medium.com/@adambisek/how-to-check-minimum-required-node-js-version-4a78a8855a0f#.3oslqmig4

.nvmrc

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

但是,它只受到 npm 脚本(和 yarn 脚本)的尊重。


这是 2019 年的最佳答案,因为设置引擎已被弃用,而且许多人(可能)由于使用 nvm 切换版本而遇到这种情况。
这假设 @babel/node 已安装。
C
Ciro Santilli Путлер Капут 六四事

.nvmrc

如果您是 using NVM like this,您可能应该这样做,那么您可以在 git-tracked .nvmrc 文件中指明给定项目所需的 nodejs 版本:

node --version > .nvmrc

或者:

echo v10.15.1 > .nvmrc

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

nvm use

现在该版本的节点将用于当前外壳。

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

nvm list

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

cd 上询问如何自动选择该节点版本:Automatically switch to correct version of Node based on project

使用 NVM 0.33.11 测试。

.nvmrc 与 package.json engines

您可能想要做的是:

使用 package.json 中的引擎来给出“没有已知的不兼容性范围”

给 .nvmrc 设置一个“tested with”

很像 package.json 与 package-lock.json。

Heroku 确实尊重 package.json engines:

值得一提的是,作为 documented here,Heroku 确实玩得很好,并遵守 engines: 条目,例如:

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

因此,您应该 Always, Always 将其设置为您在本地使用的内容。

之前在此 self deleted answer to this thread 中已提及这一点。


nvm use 不为 nvm 版本 1.1.7 选择 .nvmrc
@AakashVerma 嗯,快速浏览一下,nvm 只升级到 0.37.2 版,并且 nvmrc 仍然记录在 master 上:github.com/nvm-sh/nvm/tree/… 如果你弄清楚了,请告诉我。
@AakashVerma 我猜你正在使用 github.com/coreybutler/nvm-windows/releases 正如他们在自述文件中提到的“原始 nvm 是一个完全独立的项目,仅适用于 Mac/Linux。这个项目使用完全不同的理念,而不仅仅是 nvm 的克隆”所以这并不奇怪。考虑在他们的跟踪器上打开功能请求。
似乎有一个最近的 PR 正在等待这个 github.com/coreybutler/nvm-windows/pull/594
v
vnglst

还有另一种更简单的方法可以做到这一点:

npm install Node@8(将 Node 8 保存为 package.json 中的依赖项)您的应用程序将使用 Node 8 为任何人运行 - 甚至是 Yarn 用户!

这是因为 node 只是一个将 node 作为其包二进制文件的包。它只包含 node_module/.bin 这意味着它只使节点可用于打包脚本。不是主壳。

在此处查看 Twitter 上的讨论:https://twitter.com/housecor/status/962347301456015360


我不同意,这可能会隐藏问题,并且如果未安装节点,它会旁加载不同版本的节点。
-1 因为这是一个糟糕(非常糟糕)的想法。这就像说,如果你失业了,你应该先资助一家公司,然后你就可以开始在那里工作。
对我来说听起来是个好主意。单独项目的单独节点版本。可以安全地升级一个而不升级其他的。只有 catch 必须在 .bin ./node node-sass 中运行,而不仅仅是 node-sass。不确定所有 .bin 文件是否相同。
这是一个简单而优雅的解决方案——只要从事产品工作的团队成员知道正在发生这种情况,我认为这是一个很好的答案。我们在一家大公司使用这种技术来处理十几个 Web 前端产品的各种 Node 版本。在产品之间来回切换时,无需使用 nvm 进行持续切换。
该解决方案有其自身的优点和缺点。节点版本封装可能是它最大的优点。如果您打算以这种方式部署它,缺点是 docker 映像大小臃肿。
l
leonbloy

这是我基于 Adam's answer 的完整即用型脚本。

check-version.js

/* 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.jsonengines 条目)中指定的,例如

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

您可以手动调用它

node check-version.js [verbose]

或将其作为脚本包含在 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"
},

J
Jamie Nicholl-Shelley

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);
    });});

不应该是单元测试,使用 package.json /dotfiles
但是whhhhhhhy,为此设计了一个单元测试>.-
因为你需要 Node 来运行单元测试。如果存在的节点版本太过时,测试将根本无法运行,或者它们会因语法错误或smth而失败。类似,这违背了单元测试的意义。这就像在授权表单后面隐藏密码重置表单。如果忘记密码,需要使用重置密码功能,但现在不能使用,因为不记得密码了。
我的假设是至少安装了一个最小的软件包。为什么还要强制执行一个特定的。
@JamieNicholl-Shelley 不!单元测试不是为此而设计的!你有没有看到 go.mod 是如何指定 go 的版本,... pom.xml 是指定 java 的版本!我们需要saaaame!知道了?