使用环境变量
在 npm script 中,我们可以利用环境变量来提高脚本的灵活性和可维护性。npm 在执行脚本时,会将 package.json 中的配置和依赖信息注入到环境变量中,供脚本直接使用。这些变量以 npm_package_ 或 npm_config_ 开头。
遵循 DRY (Don't Repeat Yourself) 原则,通过使用预定义和自定义变量,我们可以编写出更具适应性和可移植性的 npm script,轻松地将脚本复用至不同项目,而无需修改。
使用预定义变量
npm 提供了丰富的预定义变量。你可以通过 npm run env 命令查看当前项目所有可用的环境变量。其中,npm_package_* 系列变量包含了 package.json 中的所有字段信息。
例如,以下是一些常见的预定义变量:
npm_package_name=your-project-name
npm_package_version=1.0.0
npm_package_author_name=author
npm_package_scripts_test=mocha
npm_package_devDependencies_mocha=^8.0.0在脚本中,你可以通过 $ 符号(在 Windows 的 CMD 中是 %)来引用这些变量。例如,$npm_package_name 会被替换为项目的名称。
实战:按版本归档测试覆盖率报告
一个常见的需求是追踪测试覆盖率的变化趋势。我们可以将每次生成的覆盖率报告按照项目的版本号进行归档。
假设我们使用 nyc 来生成覆盖率报告,可以修改 package.json 中的 scripts 如下:
{
"name": "hello-npm-script",
"version": "0.1.0",
"scripts": {
"test": "mocha",
"cover": "nyc --reporter=html npm test",
"cover:cleanup": "rm -rf coverage .nyc_output",
"cover:archive": "mkdir -p coverage_archive/$npm_package_version && cp -r coverage/* coverage_archive/$npm_package_version",
"postcover": "npm run cover:archive && npm run cover:cleanup && opn coverage_archive/$npm_package_version/index.html"
}
}这里的脚本协同工作如下:
cover:archive:mkdir -p coverage_archive/$npm_package_version: 使用项目版本号创建一个用于归档的目录。cp -r coverage/* ...: 将coverage目录下的报告文件复制到新建的版本归档目录中。
postcover: 这是一个钩子脚本,在npm run cover执行成功后自动运行。npm run cover:archive: 执行归档操作。npm run cover:cleanup: 清理本次生成的临时文件。opn ...: 自动在浏览器中打开归档后的覆盖率报告。
执行 npm run cover 后,项目根目录下会生成 coverage_archive/0.1.0/ 这样的目录结构,其中包含了本次运行的覆盖率报告。
使用自定义变量
除了 npm 提供的预定义变量,我们还可以在 package.json 的 config 字段中定义自己的变量。这些变量可以通过 npm_package_config_* 的形式在脚本中引用。
实战:为覆盖率报告启动一个 Web 服务
为了方便团队成员查看覆盖率报告,我们可以启动一个简单的 HTTP 服务来托管报告页面。我们可以将端口号定义为自定义变量,以方便修改。
首先,安装一个轻量的 HTTP 服务工具 http-server:
npm install http-server --save-dev然后,在 package.json 中添加 config 字段并更新 scripts:
{
"name": "hello-npm-script",
"version": "0.1.0",
"config": {
"port": "3000"
},
"scripts": {
"test": "mocha",
"cover": "nyc --reporter=html npm test",
"cover:cleanup": "rm -rf coverage .nyc_output",
"cover:archive": "mkdir -p coverage_archive/$npm_package_version && cp -r coverage/* coverage_archive/$npm_package_version",
"cover:serve": "http-server coverage_archive/$npm_package_version -p $npm_package_config_port",
"cover:open": "opn http://localhost:$npm_package_config_port",
"postcover": "npm-run-all cover:archive cover:cleanup --parallel cover:serve cover:open"
}
}相关改动说明:
- 在
config对象中,我们定义了port变量。 cover:serve脚本使用http-server启动服务。它通过$npm_package_version找到正确的报告路径,并使用$npm_package_config_port来设置服务端口。postcover脚本使用npm-run-all来编排多个任务,其中cover:serve和cover:open是并行执行的,因为cover:serve是一个常驻进程。
现在,再次运行 npm run cover,终端会启动 http-server 并保持运行状态,同时浏览器会自动打开 http://localhost:3000,显示覆盖率报告页面。
注意:自定义变量的声明不支持引用其他变量。例如,在
config字段中{"path": "$npm_package_version/foo"}是无效的。
通过结合使用预定义和自定义变量,我们可以创建出高度灵活且易于维护的 npm script,从而显著提升开发工作流的自动化水平。
本节用到的代码见 GitHub,想边看边动手练习的同学可以拉下来自己改,注意切换到正确的分支
05-use-config-variables。