限定項目運行所需的 Node.js 版本可保證項目在一個穩定可預期的環境中運行,減少不必要的故障。甚至有些依賴庫只能工作於某些版本下。同時,不加以限制的話,在多人合作的項目中恐怕會引起環境不一致帶來的兼容性問題,部署上也會存在相同的問題。
為項目指定 Node.js 的版本可通過版本管理器,或者通過 package.json 中添加相應屬性來實現。
nvm
管理 Node.js 的版本最好可通過相應的版本管理器來完成,比如 nvm。用法在 nvm --help
中描述得很詳盡。
通過在項目根目錄創建一個 .nvmrc
,其中寫上需要的 Node.js 版本號。這個版本號不一定是數字,可以是 nvm 能夠理解的其他別稱,詳見 nvm --help
中對 <version>
的描述。
Note: <version> refers to any version-like string nvm understands. This includes:
- full or partial version numbers, starting with an optional "v" (0.10, v0.1.2, v1)
- default (built-in) aliases: node, stable, unstable, iojs, system
- custom aliases you define with
nvm alias foo
-- nvm 幫助信息中對 版本號的描述
示例:
# 將當前版本寫入
$ node -v > .nvmrc
# 使用 5.9 的版本
$ echo "5.9" > .nvmrc
# 使用最新的 LTS (Long-term Support) 版本
$ echo "lts/*" > .nvmrc
# 使用最新的 Node.js 版本
$ echo "node" > .nvmrc
在執行如下這些命令時,會自動讀取 .nvmrc
中版本號以應用上,
nvm use
nvm install
nvm exec
nvm run
nvm which
這樣協作者將項目 clone 下來后直接 nvm use
就直接切換到相應版本,如果本地沒有安裝,nvm install
則會安裝相應版本。
engines
根據 npm-package 文檔的描述,可以在 package.json
中通過 engines
屬性指定 Node.js 的版本。
{
"engines": { "node": ">=0.10.3 <0.12" }
}
甚至可以限定 npm 的版本:
{
"engines": { "npm": "~1.0.20" }
}
有趣的是,在執行 npm install
安裝項目依賴時,這個設置並不生效,相反,非官方的 yarn 是有效(respect)的,它會檢查這里的設置,如果當前環境與所需不匹配,直接報錯,這是我們期望的結果:
yarn 執行安裝前檢查版本不對時拋錯
所以推薦使用 yarn。
如果使用的 npm 怎么辦呢。只能手動寫腳本來做這個事情了。
$ npm i -D semver
$ touch checkver.js
實現我們檢查版本的邏輯:
checkver.js
const semver = require("semver");
const { engines } = require("./package");
const version = engines.node;
if (!semver.satisfies(process.version, version)) {
console.error(</span>Required node version <span class="pl-s1"><span class="pl-pse">${</span>version<span class="pl-pse">}</span></span>, got: <span class="pl-s1"><span class="pl-pse">${</span><span class="pl-c1">process</span>.<span class="pl-c1">version</span><span class="pl-pse">}</span></span>.<span class="pl-pds">
);
process.exit(1);
}
添加 postinstall
命令到 package.json:
{
"scripts": {
"postinstall": "node ./checkver.js"
}
}
運行效果:
使用 `postinstall` 執行 Node.js 版本的檢查
為什么使用 postinstall
呢,如果使用 preinstall
豈不是更好,這樣在執行安裝前就能檢查。但這里我們依賴了 semver 這個 npm 包,所以需要讓安裝先執行。