根据节点版本安装不同的包

Install different packages depending on node version

我有一个项目依赖于 websocket 包。但是,对于节点 10.x,websocket 的最新版本 (1.0.31) 有效,而在节点 4.x 上,版本 10.0.24 有效,但 10.0.31 不[=22] =].是否可以为每个 nodejs 版本指定 different 包(版本)来处理这样的情况,例如像这样

  • node 4.x 及更早版本 -> websockets 1.0.24
  • 所有其他节点版本 -> websockets 1.0.31

最好它应该在 npm 和 yarn 中都工作,但如果它只在其中一个中工作也很好。

节点 10 版本用于开发设置,而节点 4.x 用于无法 运行 docker 或升级的遗留嵌入式平台。

考虑在项目 scripts 部分使用 postinstall 脚本 package.json。例如:

package.json

"scripts": {
  "postinstall": "node install-websocket"
},

如您所见,postinstall 脚本调用了一个任意命名为 install-websocket.js.

的 nodejs 脚本

安装-websocket.js

const execSync = require('child_process').execSync;

const nodeMajorVersion = process.version.replace(/^v/, '').split('.')[0];
const websocketVersion = nodeMajorVersion <= '4' ? '1.0.24' : '1.0.31';

execSync('npm install websocket@' + websocketVersion, {
    cwd: __dirname,
    stdio: 'inherit'
});

install-websocket.js 脚本主要执行以下任务:

  1. 使用 process.version 获取 node.js 的版本,其中 returns 一个字符串,例如v13.10.1

    为了从该字符串中获取 Major 版本(即上述示例中的 13),我们使用 replace() and split() 方法的组合。

  2. conditional (ternary) operator查明 随后安装 websocket 的哪个版本 - 基于 nodeMajorVersion 的值是否为 <= 4.

  3. 最后我们 "shell out" 使用 execSync.

    适当的 npm install websocket@x.x.x 命令

    注意:如果您担心 execSync 是同步的,请改用异步 exec


补充说明:

  • 鉴于上面显示的代码,它假定 install-websocket.js 文件位于项目目录的根目录中,即与 package.json.

    my-project
    ├── package.json
    ├── install-websocket.js
    └── ...
    

    由于以下两个原因,install-websocket.js 文件存在于此位置很重要:

    1. 首先,也是最重要的,因为您会注意到我们指定了 __dirname for the value of execSync's cwd 选项。在此上下文中 __dirname 的值是 install-websocket.js 文件所在父目录的路径名。

      基本上通过将 cwd 选项设置为这个特定的路径名​​,(即项目目录的路径),我们确保当 npm install websocket@x.x.x 命令是 运行 它被安装与您的项目所在的位置相同 - 无论它是本地安装还是全局安装。

    2. package.json 中的 postinstall 脚本希望 install-websocket.js 文件也驻留在那里。注意它目前如何 运行s; node install-websocket,并且不假设文件存在于其他地方,即它不是 运行ning 类似的东西:node ./some/path/to/install-websocket

  • 如果你的包的消费者有 npm 那么 websocket 将不会被安装,因为 postinstall 脚本将不会被调用。