「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」
声明
本文中提到的爱情故事的情节纯属虚构,请各位不要被破防,流泪,砸手机。
一个问题 && 错误的答案
【故事时间】
小瑞是一个人类高质量男性,中分飘飘,油光锃亮。于是,他的生活中出现了两个追求他的女生。
其中
小依是一个乖乖女,她的英文名叫dependencies,大家都觉得她是过日子的类型,一定是将来的新娘;
而
小开则是一个开放又浑身魅力的女生,英文名叫devDependencies,大家给她的评价是,适合在谈恋爱时交往,但最后和小瑞结婚的肯定不是她。
那么问题来了:
对于
小瑞而言,小依和小开的区别到底有多大?本质上的区别又在哪里呢?
【技术时间】
现代前端项目离不开npm,哪怕有了yarn/pnpm/ni等一系列的替代工具,但我们依然离不开npm所带来的标准。
而package.json文件,无疑是其中的关键。
但是,你能快速回答出下面这个问题吗?
dependencies和devDependencies对于你的项目而言,本质区别到底是什么?
很多同学对于这个知识点,只有一个模糊的认知,甚至于是来自于语义上的认知:
dependencies里的依赖最后会构建到制品包里去;
devDependencies里的依赖只在开发期有效;
回答的很好,可惜:
🔺🔺❌❌完全错误❌❌🔺🔺
语义化并不能完全指引你走向正确的道路,反而可能会走向歧路。
那么正确答案是什么呢?
看看小瑞怎么说?
寻根问底 && 真正的差异
【故事时间】
小瑞虽然是个渣男,但他还是想弄清楚:“对于他而言,小依和小开真正的区别是什么?”
于是他找到了
小依和小开的全部资料,扒掉伪装,深入本质,把握重点...
终于,小瑞得到了一个让他有点犯懵的结论:
虽然有一些差距,但如果只是把范围局限到对他而言上的话,
小依和小开的区别竟然微乎其微!
💗💗💗💗怎么可能?💗💗💗💗
【技术时间】
对于技术人员而言,真正可靠的差异,还得是 百度和问群友 看文档。
npm官方文档地址: docs.npmjs.com/specifying-…
官方文档里怎么说?
"dependencies":您的应用程序在生产中所需的包。
"devDependencies": 只需要本地开发和测试的包。
看到这儿某些同学放声大笑:“这不就是我刚才的答案吗?”
很抱歉,这也只是它们的定义和语义化约定,做不得数的!!
真正的区别,其实在这里:
差异一:
By default, npm install will install all modules listed as dependencies in package.json.
翻译一下:
默认情况下,npm install将安装package.json里所有列为dependencies的模块。
笔者解释:
- 这种依赖是向下遍历的,比如A库依赖B库,B库依赖C库,在A库中npm install时,会同时安装B和C!
- 但是devDependencies却不是,npm install 时只会在node_modules里安装当前项目的devDep;比如A的开发依赖是B,B的开发依赖是C,在A库里npm install,只会安装B!
如下图:实线表示dependencies, 虚线表示devDependencies
当我们执行npm install时,对于当前根项目(图中的A项目)而言,dependencies和devDependencies对它而言,表现上是一模一样的,都将资源安装到了node_modules中。
一旦资源被安装到了node_modules中,对于后续的开发和构建而言,程序就更加无法感知到它们的区别。
👧👧👧小瑞心想:呵,陷入爱情的女人,一般无二👧👧👧
但是!!
再往下看,到了D/E/F/G这一层依赖时,dependencies和devDependencies的区别就凸现出来了。
在第三层里,所有被上一层dependencies的库,都得以安装,所有devDependencies里的,都未能被安装。
如果你仍有疑虑,可以尝试做个验证:
mkdir test-dep
cd test-dep
yarn init
yarn add -D fast-glob
然后打开项目,去node_modules中验证一番,是否符合我们刚才得出的结论:
正常情况下,dependencies和devDependencies的影响不是直接的,而是跨代的!
【吐槽时间】
好家伙,这波是对舔狗的杀人诛心了,可谓是。
小瑞在无形中,对
小依和小开的追求者,造成了深远的影响。
不过,我们严谨一点,也有例外:
With the --production flag (or when the NODE_ENV environment variable is set to production), npm will not install modules listed in devDependencies.
翻译下:
(npm install时)使用--production标志(或当NODE_ENV环境变量设置为production),npm 将不会安装devDependencies.
对,这里确实是符合语义化,“生产模式”不装“开发环境的依赖”。看到这里,我突然意识到,为什么很多项目在build脚本中要使用--production了,原来这不是约定,而是规范。
意料之外,情理之中。绝绝子的结局(有翻转)
最后这段才是真正的杀人诛心,因为它是根据**真实事件**改编!
看下去吧!
【故事时间】
小瑞发现了上面的知识点后,开始对语义化不屑一顾。
于是他决定抛开人们的成见(也就是
语义化),要娶小开为妻。
(某个著名开源团队将本应该放在devDependencies的内容放到了dependencies中。)
小瑞心想:我太懂女人了。
(该开源团队:我太懂依赖了;只要我项目里不依赖,它们就不会影响我包的体积,完美!)
👫👫👫这会是完美的结局吗?👫👫👫
非常可惜,不是。
【社区时间】
真人真事:
前端项目的denpendencies里应不应该放开发时的依赖?
create-react-app项目组在4年前的答案是“适合”,因为dep和devDep的区别主要是语义上的,并不会影响项目的构建,为了解决某些问题,忽略语义是值得的。
但万万没想到的是,第2年,npm 6就推出了audit指令,dependencies拥有了更多的意义。
非常多用户因扫描出高危漏洞而困扰。
4年前那个“讨巧”的解决方案再次被提出讨论,而且大概率会被重新扔回devDependencues里去。
这真是个悲伤的故事。
【故事时间】结局
小瑞万万没想到,他们美满的婚姻只持续了一年。
第二年,他们的婚姻就因为“社区身体普查”
小开被意外查出了_ _ _ ,而走向了破灭...
🎗️🎗️🎗️可惜不是你,陪我到最后🎗️🎗️🎗️
总结
关于技术细节,不再多说,上面都有来源,大家也可以自行验证,如果有错误,欢迎指出。
我只是想发出一点感叹:
面向“可以、有用、没关系”的解决之道可能并不长久,语义化也并不是虚妄的内容,它可能是真正面向未来的编程思维。
关于故事真实性
请参考github相关讨论:
a. github.com/facebook/cr…
b. github.com/facebook/cr…