说实话,这个话题我想写很久了。前几天帮同组的同事排查线上问题,花了两个小时才发现,原来是他把 webpack 和一堆开发工具都放到了 dependencies 里,导致生产环境打包体积大了整整一倍。我当时就想,这事儿得好好说道说道。
那些年我们犯过的"傻"
还记得我刚入门前端的时候,对 package.json 里的这两个字段完全没概念。看到别人怎么写我就怎么写,npm install 一把梭,管它什么 --save 还是 --save-dev。结果就是:
- 项目目录越来越臃肿
- CI/CD 跑得越来越慢
- 生产环境莫名其妙多了一堆用不上的包
- 甚至有时候还会因为某些开发依赖在生产环境报错
如果你也有过类似的经历,别担心,这很正常。今天我们就来彻底搞明白 dependencies 和 devDependencies 的区别。
一句话说清楚:它们到底差在哪?
dependencies :你的应用在生产环境运行时真正需要的依赖包 devDependencies:只在开发、构建、测试阶段需要的工具和库
就这么简单!但就是这么简单的区分,却能带来巨大的影响。
用生活中的例子来理解
想象一下你要做一道菜:
dependencies 就像是做菜必需的食材:鸡、鱼、蔬菜、调料。少了它们,这道菜就没法完成。
devDependencies 就像是做菜的工具:菜刀、锅、铲子、案板。这些工具帮你把食材变成美味,但最后上桌的时候,没人会把这些工具一起端上来。
实战中的判断标准
哪些应该放在 dependencies?
json
{
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"axios": "^1.0.0",
"lodash": "^4.17.21",
"moment": "^2.29.4"
}
}
这些都是你的应用代码中直接 import 或 require 的库,少了它们应用就跑不起来。
哪些应该放在 devDependencies?
json
{
"devDependencies": {
"webpack": "^5.0.0",
"babel-loader": "^9.0.0",
"eslint": "^8.0.0",
"jest": "^29.0.0",
"sass-loader": "^13.0.0",
"webpack-dev-server": "^4.0.0"
}
}
这些都是开发工具链上的东西:打包工具、编译器、代码检查工具、测试框架等。
为什么要严格区分?这不只是代码洁癖
1. 生产环境安装优化
当你运行 npm install --production
或 yarn install --production
时,只会安装 dependencies 中的包。如果你把开发工具也放到了 dependencies 里:
- 部署包体积可能增加 30-50%
- 安装时间成倍增长
- 服务器资源浪费严重
2. 安全风险降低
开发依赖中可能包含一些安全漏洞,但这些漏洞在生产环境中并不需要。严格区分可以减少攻击面。
3. 版本冲突避免
某些开发工具可能和生产依赖有版本冲突,分开管理可以避免这类问题。
常见的误区和坑
误区一:把所有 @types 包都放 dependencies
json
// ❌ 错误做法
{
"dependencies": {
"@types/react": "^18.0.0",
"@types/node": "^18.0.0"
}
}
TypeScript 的类型定义文件只在开发时需要,运行时完全不需要,应该放在 devDependencies 中。
误区二:把构建工具放 dependencies
json
// ❌ 错误做法
{
"dependencies": {
"webpack": "^5.0.0",
"gulp": "^4.0.0",
"babel-core": "^6.0.0"
}
}
这些构建工具在生产环境完全用不到,应该放在 devDependencies 中。
误区三:把测试框架放 dependencies
json
// ❌ 错误做法
{
"dependencies": {
"jest": "^29.0.0",
"mocha": "^10.0.0"
}
}
测试框架只在开发和 CI 环境使用,生产环境不需要。
实用的判断方法
当你不确定一个包该放哪时,问自己几个问题:
- 我的应用代码里有没有 import 或 require 这个包?
- 如果把这个包从生产环境移除,应用还能正常运行吗?
- 这个包主要是在开发、构建、测试时使用吗?
如果前两个问题的答案是"没有",第三个是"是",那它就应该放在 devDependencies 中。
一个小技巧:批量迁移依赖
如果你的项目已经很乱了,可以用这个小技巧:
bash
# 把某个包从 dependencies 移到 devDependencies
npm uninstall package-name
npm install package-name --save-dev
# 或者直接编辑 package.json,然后运行
npm install
写在最后
区分 dependencies 和 devDependencies 看似小事,但它体现了一个开发者的专业素养。一个干净的 package.json 不仅能提升项目性能,更能体现你对项目的理解和掌控能力。
下次再看到别人的 package.json 时,不妨偷偷瞄一眼他们的依赖管理是否规范。说不定你还能帮他们发现一些隐藏的问题呢!
记住:好习惯从每一次 npm install 开始。别再让 --save-dev 成为你的陌生词汇了!
如果你觉得这篇文章对你有帮助,欢迎分享给更多还在纠结依赖管理的朋友们。让我们一起写出更干净、更专业的前端项目!