拆分到单独文件
随着项目复杂度的增加,package.json 中的 scripts 对象可能会变得异常庞大和混乱,这会严重影响其可读性和可维护性。一个有效的解决方案是将这些复杂的脚本逻辑拆分到独立的文件中。
scripty 是一个轻量级的工具,它能帮助我们实现这一目标。通过将脚本移至单独的文件,我们可以将复杂性隔离开来,使 package.json 保持整洁,并让整个工作流更加清晰。
为什么要拆分脚本?
当单个脚本命令超过一行,或者多个脚本之间存在复杂的调用关系时,就应该考虑将其拆分。例如,一个完整的测试覆盖率任务可能包括清理、运行测试、归档报告和启动服务等多个步骤,这些逻辑都堆积在 package.json 中会非常臃肿。
使用 scripty 进行重构
以下演示了如何将一组复杂的 cover 相关脚本拆分到独立文件中。
1. 安装 scripty
npm install scripty --save-dev2. 创建脚本目录和文件
scripty 默认在项目根目录的 scripts/ 文件夹中查找脚本。其文件路径与 npm script 命令的名称直接对应。
npm run cover->scripts/cover.shnpm run cover:serve->scripts/cover/serve.shnpm run cover:open->scripts/cover/open.sh
根据这个约定,我们创建相应的目录和文件:
# 创建目录
mkdir -p scripts/cover
# 创建脚本文件
touch scripts/cover.sh
touch scripts/cover/serve.sh
touch scripts/cover/open.sh
# 赋予所有脚本可执行权限
chmod +x scripts/**/*.sh3. 编写独立的脚本文件
现在,我们将原本在 package.json 中的逻辑移到这些 .sh 文件中。在这些独立的脚本文件中,我们依然可以访问 npm 提供的所有环境变量(如 $npm_package_version)。
scripts/cover.sh (合并了清理、测试、归档和预览的逻辑)
#!/usr/bin/env bash
# 1. 清理旧的覆盖率报告
rimraf coverage .nyc_output
# 2. 运行测试并生成新的覆盖率报告
nyc --reporter=html npm test
# 3. 按版本号归档报告
mkdir -p coverage_archive/$npm_package_version
cp -r coverage/* coverage_archive/$npm_package_version
# 4. 启动服务并打开浏览器
npm-run-all --parallel cover:serve cover:openscripts/cover/serve.sh
#!/usr/bin/env bash
http-server coverage_archive/$npm_package_version -p $npm_package_config_portscripts/cover/open.sh
#!/usr/bin/env bash
# 等待1秒,确保HTTP服务已成功启动
sleep 1
opn http://localhost:$npm_package_config_port注意:这些示例使用了 Bash 脚本。对于需要跨平台兼容的复杂逻辑,推荐使用 Node.js 脚本(将在下一节介绍)。
4. 更新 package.json
最后,我们清理 package.json 中的旧脚本,让它们统一调用 scripty。
{
"scripts": {
"test": "cross-env NODE_ENV=test mocha tests/",
"lint": "eslint .",
"cover": "scripty",
"cover:serve": "scripty",
"cover:open": "scripty"
}
}现在,package.json 变得非常简洁。当我们运行 npm run cover 时,scripty 会自动找到并执行 scripts/cover.sh 文件。
5. 测试运行
执行 npm run cover,你会看到 scripty 在执行脚本前会打印出将要运行的命令内容,这对于调试非常有用。最终的执行结果应与拆分前完全一致。
scripty 还支持并行执行、通配符匹配等高级功能,详情可查阅其官方文档。
通过这种方式,我们成功地将复杂的脚本逻辑封装到了独立的文件中,极大地提升了项目的可维护性。
本节用到的代码见 GitHub,想边看边动手练习的同学可以拉下来自己改,注意切换到正确的分支
07-manage-complexity-using-scripty。