npm 工具有哪些?如何按项目场景选择?
npm 生态里的工具很多,但项目里真正值得长期保留的,通常只解决几类问题:依赖更新、依赖清理、安全扫描、包体积控制、脚本编排、文档测试、构建开发、发布和 Git 工作流。
选工具时不要先问“有哪些”,而要先问“现在项目最卡在哪里”。依赖老旧就看 npm-check-updates;怀疑装了没用的包就跑 depcheck;发布前担心漏文件就检查 packlist;团队提交质量不稳定,再加 husky 和 lint-staged。
依赖更新:先看影响范围,再决定升不升
npm-check-updates:批量检查 package.json 版本
npm-check-updates 常用来检查 package.json 里的依赖是否有新版本。它不会直接安装依赖,通常先改版本声明,再由 npm、pnpm 或 yarn 重新安装。
不一定要全局安装,临时使用可以这样跑:
bashnpx npm-check-updates npx npm-check-updates -u npm install
常见用法:
bash# 只看生产依赖 npx npm-check-updates --dep prod # 只更新 patch,适合保守升级 npx npm-check-updates -u --target patch # 只更新 minor npx npm-check-updates -u --target minor # 使用指定 registry npx npm-check-updates --registry https://registry.npmmirror.com
它适合做“依赖升级前的体检”。如果项目稳定性要求高,不建议直接 ncu -u 后一把安装,最好先升级 patch/minor,再单独评估 major 版本。
npm-check:交互式查看依赖状态
npm-check 更适合人工巡检。它会把依赖更新、未使用依赖、缺失依赖等信息放在交互界面里,适合本地排查,不太适合放进 CI 阻塞流程。
bashnpx npm-check npx npm-check -u npx npm-check --ignore-unused
如果团队已经有 Renovate、Dependabot 之类的自动升级工具,npm-check 的价值会下降,但它仍然适合在大版本升级前快速扫一遍项目状态。
depcheck:找出未使用和缺失依赖
depcheck 用来检查两类问题:
package.json里写了,但代码里可能没用到的包;- 代码里引用了,但
package.json里可能没声明的包。
bashnpx depcheck npx depcheck ./src npx depcheck --ignore-patterns=dist,coverage
它的结果需要人工判断。比如 Babel、ESLint、Vite、Webpack 插件可能只出现在配置文件里,动态 import、约定式插件也可能被误判。比较稳妥的做法是:先用它生成候选清单,再结合构建、测试和运行结果删除依赖。
安全审计:npm audit 负责底线,Snyk 补充风险视角
npm audit:内置漏洞扫描
npm audit 是 npm 自带的安全检查,适合每个项目默认开启。
bashnpm audit npm audit --audit-level=high npm audit fix --dry-run npm audit fix
npm audit fix --force 要谨慎,它可能引入破坏性升级。生产项目更推荐先看 --dry-run 结果,再决定是否手动升级关键包。
如果只关注生产依赖,新版 npm 更推荐使用:
bashnpm audit --omit=dev npm audit fix --omit=dev
Snyk:适合需要持续监控的项目
Snyk 的优势是漏洞库、修复建议和项目监控更完整,适合团队项目、开源库和对安全要求较高的业务。
bashnpx snyk auth npx snyk test npx snyk test --severity-threshold=high npx snyk monitor
GitHub Actions 里可以只阻塞高危漏洞:
yaml- name: Snyk security check uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high
retire.js:更适合检查旧前端资源
retire 主要用于识别 JavaScript 库的已知漏洞,尤其是老项目里直接放在 public、vendor、static 目录下的前端库。
bashnpx retire --path ./public npx retire --path ./dist --outputformat json
如果项目完全通过 npm 管理依赖,优先级通常是 npm audit 和 Snyk;如果项目里还有手工复制的 jQuery、Bootstrap、旧插件文件,retire 就很有用。
包体积和发布内容:别等用户下载完才发现问题
npm-packlist 与 npm pack:确认发布包会包含什么
发布 npm 包前,最怕两件事:源码漏了,或者测试文件、截图、临时文件被打进去了。
可以先用 npm 自带命令检查:
bashnpm pack --dry-run npm pack --dry-run --json
如果需要和 npm 实际打包规则保持一致,可以使用 npm-packlist 做更细的检查。它会参考 files、.npmignore、.gitignore 等规则,判断哪些文件会进入最终包。
发布库时建议重点看:
dist或构建产物是否存在;- 类型声明文件是否被包含;
- README、LICENSE 是否存在;
- 测试数据、私有配置、临时日志是否误入包内。
bundlephobia:评估依赖对前端包体积的影响
Bundlephobia 适合在新增依赖前看一眼包大小,尤其是浏览器端项目。
可以直接访问 Bundlephobia 网站搜索包名,也可以把它当成评审习惯:新增一个工具库前,先看它的 minified、gzipped 体积,以及是否会带来一串间接依赖。
典型场景:
- 为一个小函数引入大型工具库;
- 日期处理库替换;
- 图表、富文本、拖拽库选型;
- SDK 是否应该按需加载。
cost-of-modules:看依赖安装成本
cost-of-modules 会统计依赖安装后的体积和成本,适合用来发现“一个小功能带来一大包依赖”的情况。
bashnpx cost-of-modules npx cost-of-modules --json
它不必每次 CI 都跑,更适合在项目依赖明显膨胀、安装变慢、容器镜像变大时做分析。
脚本编排:npm-run-all 和 concurrently 分工不同
npm-run-all:适合组合 npm scripts
npm-run-all 解决的是“多个脚本按顺序或并行执行”的问题。
bashnpm install -D npm-run-all
json{ "scripts": { "clean": "rimraf dist", "lint": "eslint src", "test": "vitest run", "build": "webpack --mode production", "check": "run-p lint test", "release:build": "run-s clean check build" } }
常用命令:
bashrun-s clean build test run-p lint test run-s clean "run-p lint test" build
run-s 表示顺序执行,run-p 表示并行执行。它更适合一次性任务,比如构建、测试、发布前检查。
concurrently:适合同时启动长期进程
concurrently 更适合开发环境,比如同时启动前端、后端和测试监听。
bashnpm install -D concurrently
json{ "scripts": { "dev:api": "nodemon server.js", "dev:web": "vite", "dev": "concurrently --names API,WEB --prefix-colors blue,green \"npm run dev:api\" \"npm run dev:web\"" } }
常用参数:
bashconcurrently "npm run dev" "npm run test:watch" concurrently --kill-others "npm run api" "npm run web" concurrently --names "API,WEB" "npm run api" "npm run web"
简单判断:短任务编排用 npm-run-all,长期进程并跑用 concurrently。
文档和测试:先覆盖公共 API,再追求漂亮页面
jsdoc:适合从注释生成 API 文档
jsdoc 适合传统 JavaScript 项目,也适合给公共函数、类、模块生成 API 文档。
bashnpm install -D jsdoc npx jsdoc src -d docs npx jsdoc -c jsdoc.conf.json
如果项目已经大量使用 TypeScript,JSDoc 的重点可以放在“说明行为和边界”,不要把类型信息重复写一遍。
documentation:适合生成 Markdown 或 HTML 文档
documentation 更适合把 API 文档输出成 Markdown、HTML 或 JSON,方便放进站点或 README。
bashnpm install -D documentation npx documentation build src -f html -o docs npx documentation build src -f md -o API.md npx documentation build src -f json -o api.json
对开源库来说,文档工具的价值不只是生成页面,而是逼你确认公共 API 是否稳定、参数是否清楚、异常行为是否写明。
nyc:统计测试覆盖率
nyc 是 Istanbul 的命令行工具,适合 Mocha、AVA 等测试框架,也能配合很多 Node.js 测试命令使用。
bashnpm install -D nyc npx nyc npm test npx nyc report --reporter=html npx nyc --check-coverage --lines 80 npm test
覆盖率阈值不要一开始就设得很高。老项目可以先记录基线,再逐步提高;新项目可以对核心目录设置更严格的要求。
testdouble:让单元测试少依赖外部环境
testdouble 用来创建测试替身,适合隔离网络请求、文件系统、数据库访问等外部依赖。
bashnpm install -D testdouble
jsconst td = require('testdouble') const send = td.function('send') send('hello') td.verify(send('hello'))
如果项目已经使用 Jest 或 Vitest 自带 mock,未必需要再引入 testdouble;但在偏函数式、模块边界清晰的 Node.js 项目里,它的表达会比较直接。
构建和开发:webpack、rollup、nodemon、live-server 各有位置
webpack:适合应用型项目
Webpack 的优势是生态成熟,处理复杂前端应用很稳,尤其是多类型资源、代码分割、Loader/Plugin 定制较多的项目。
bashnpm install -D webpack webpack-cli npx webpack --config webpack.config.js npx webpack --mode production npx webpack --watch
如果项目是大型 Web 应用,且已有复杂配置,继续使用 webpack 很正常;如果是新项目,也可以结合 Vite 等工具评估启动速度和配置成本。
rollup:适合库和组件包
Rollup 更适合打包库,尤其是希望输出 ESM、CJS、UMD 多种格式,并保持较好 tree-shaking 的项目。
bashnpm install -D rollup npx rollup -c npx rollup -c -w
常见选择是:应用用 webpack/Vite,库用 rollup/tsup。工具不是越统一越好,关键是产物形态和维护成本合适。
nodemon:Node 服务开发时自动重启
nodemon 会监听文件变化并重启 Node.js 进程,适合 API 服务、本地脚本、CLI 开发。
bashnpm install -D nodemon
json{ "scripts": { "dev": "nodemon app.js", "dev:debug": "nodemon --inspect app.js", "dev:watch": "nodemon --watch src app.js" } }
live-server:简单静态页面预览
live-server 适合预览静态 HTML、构建后的 demo 或文档站点,不适合复杂前端应用的正式开发服务器。
bashnpx live-server npx live-server --port=8080 npx live-server --root=dist npx live-server --ignore=node_modules
如果只是临时看一个 dist 目录,它很方便;如果项目已经用 Vite、Next.js、Nuxt 或自带 dev server,就没必要再加一层。
发布自动化:np 适合人工确认,semantic-release 适合机器发布
np:让手动发布更稳
np 会帮你做发布前检查,比如工作区是否干净、测试是否通过、版本号和 tag 是否正确。它适合仍然希望人工确认版本和发布动作的 npm 包。
bashnpm install -D np npx np npx np 1.2.3 npx np --tag beta
np --yolo 会跳过不少检查,除非是临时包或内部包,否则不建议作为常规流程。
semantic-release:根据提交记录自动发版
semantic-release 适合成熟团队和持续发布场景。它通常依赖 Conventional Commits,根据 commit 类型自动判断版本、生成 release notes,并发布到 npm 或 GitHub。
bashnpm install -D semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/npm @semantic-release/github
.releaserc.json 示例:
json{ "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/npm", "@semantic-release/github" ] }
如果团队提交信息不规范,先上 semantic-release 反而会痛苦。可以先用 commitlint 和 husky 把提交格式稳定下来。
Git 工作流:husky 和 lint-staged 管住提交入口
husky:管理 Git hooks
Husky 用来把检查命令挂到 Git hooks 上,例如提交前跑 lint、提交信息校验等。
现代版本通常这样初始化:
bashnpm install -D husky npx husky init
然后编辑 .husky/pre-commit:
bashnpm test
或者只跑更快的检查,避免每次提交都等很久。
lint-staged:只检查暂存文件
lint-staged 的价值是“只处理这次提交涉及的文件”,比全量 lint 更快。
bashnpm install -D lint-staged
json{ "lint-staged": { "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"], "*.{css,scss,md,json}": ["prettier --write"] } }
新版 lint-staged 会处理修改后的文件状态,通常不需要再手写 git add。如果团队成员经常因为 hook 太慢而绕过检查,说明 hook 里放的任务太重了,应该把耗时任务挪到 CI。
一个比较实用的 package.json 组合
下面这个组合适合中小型 Node.js 或前端项目,不追求工具最多,只覆盖日常维护的关键点:
json{ "scripts": { "dev": "concurrently --names API,WEB \"npm run dev:api\" \"npm run dev:web\"", "dev:api": "nodemon server.js", "dev:web": "vite", "lint": "eslint src", "test": "vitest run", "test:coverage": "nyc npm test", "check": "run-p lint test", "deps:check": "npm-check", "deps:update": "ncu -u", "deps:unused": "depcheck", "security": "npm audit --audit-level=high", "pack:check": "npm pack --dry-run", "build": "webpack --mode production", "release": "np" }, "lint-staged": { "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"] } }
这类脚本的好处是团队不用记住每个工具的参数,只要记住几个入口:
npm run check:提交或合并前的基础检查;npm run security:安全审计;npm run deps:unused:依赖清理;npm run pack:check:发布前确认文件;npm run release:发布流程。
怎么决定工具要不要进项目
可以用几个很朴素的标准判断:
| 场景 | 推荐工具 | 是否建议进 devDependencies |
|---|---|---|
| 经常检查依赖更新 | npm-check-updates、npm-check | 可以 |
| 偶尔清理依赖 | depcheck | 可以,也可 npx 临时跑 |
| 每次 CI 做安全检查 | npm audit、Snyk | npm audit 内置,Snyk 看团队需求 |
| 发布 npm 包 | npm pack、npm-packlist、np | 建议 |
| 控制前端体积 | bundlephobia、cost-of-modules | 多数情况下临时使用即可 |
| 多脚本编排 | npm-run-all、concurrently | 建议 |
| 生成 API 文档 | jsdoc、documentation | 看项目是否对外提供 API |
| 覆盖率统计 | nyc | 建议用于库或核心服务 |
| 自动重启服务 | nodemon | 建议用于 Node 服务 |
| 提交前检查 | husky、lint-staged | 团队项目建议 |
最后要注意一点:工具本身也会增加维护成本。能用 npm 内置能力解决的,就别急着加依赖;需要团队统一入口的,再把它写进 scripts。一个项目里真正有价值的 npm 工具,不是清单最长的那组,而是大家每天都愿意运行、出了问题也知道该怎么修的那组。