背景
在做公司内部lint
包的时候,碰到了一个问题:Cannot find module 'xxxx'
流程是这样的:
- 在
npm-spec
(公司内部lint
包)的devDependencies
下添加“eslint-config-alloy
”:”catalog:eslint8
”,不清楚“catalog:eslint8
”的朋友可以看我这篇文章 - 在模板工程中安装
npm-spec
,并在 .eslintrc.js
引入依赖
然后我在工程化项目的模板示例上验证是ok
的,满怀期待的基于cli
创建工程模板验证的时候,就出现了上面的问题,lint
不生效(what
?!震惊脸)
排错
因为我习惯了使用pnpm
安装,所以第一反应就去看node_modules
查看依赖,果然在依赖中没看到 eslint-config-alloy
的身影,大家也都知道pnpm
解决了“幽灵依赖”的问题。
所以上面的问题也就容易推算出来,是因为eslint-config-alloy
没有安装到宿主的依赖中去,那是什么原因导致了这个安装问题呢?下面就引出这期的主角:dependencies
和 devDependencies
旧观念
dependencies
放的是生产依赖,所以需要打包到产物里的依赖都放dependencies
devDependencies
放的是非生产依赖,所以不需要打包到产物里的依赖都放devDependencies
也就是“dependencies === dist
”这样的一个观念,这从业务开发的视角看似乎没啥问题
新观念
来自官方的解释:
再结合实际安装依赖的表现,从npm
包的开发者视角来看,“dependencies === dist
”就有问题了
如果是使用npm
安装依赖,因为是依赖是平铺的,所以在使用上没造成什么问题,但如果是使用pnpm
安装依赖,那npm
包的依赖管理就得慎重起来了
反思
为什么出现这种错误认知的观念呢?是因为没有经过系统性的学习,常常是这边学一点,那边看一点,不成体系的知识树导致我们在市场中的竞争力不强。
想要系统性的学习前端体系,可以来看一看大师课,大师课包含了…(虚晃一枪,没有广告)
那如果在devDependencies
安装生产所需的依赖,会不会打包到dist
中去呢?做个验证:
很明显,哪怕依赖声明在devDependencies
中,但在实际使用中是会打包近dist
文件中的,所以只能是“dependencies == dist
”
梳理
好像有点乱,什么时候用dependencies
?什么时候用devDependencies
?这其实跟开发视角有关系
业务开发
因为最终作用生效的只有dist
资源,不作为最终产物的上下游,所以理论上无所谓依赖放在哪个地方,但出于语义化和开发规范,需要打进dist
的依赖应该加到dependencies
中
npm
开发
因为最终作用生效的不仅是dist
资源,还是作为构建最终产物的上游,dependencies
的依赖会下载到宿主的node\_modules
中,直接影响构建结果,所以对于npm
包本身所需的依赖以及宿主没有且需要的依赖,需要放在dependencies
中去
什么样的场景容易造成误判呢?下面举两个场景:
taro
插件
taro
使用插件是可以以Array<string>
方式引入的,它底层是通过读取node_modules
来查找依赖的
如果你想基于taro
的配置封装一个npm
包出来,在里面做一些优化,可能用到了部分市场插件,这时候这些插件依赖应该声明在哪个地方?
lint
配置
eslint
部分配置也是通过字符串的形式引入的,同样,如果你想做一层封装,这些依赖应该声明在哪个地方?
按业务开发视角来看很容易把这些依赖放在devDependencies
中去,但如果宿主项目没有安装这些依赖,控制台就会报错。所以应该放在dependencies
或者peerDependencies
(感兴趣的可以自行搜下这个配置)
总结
“dependencies == dist
”,而不是“dependencies === dist
”,且在做第三方库的时候需要重视你的依赖,因为dependencies
依赖会作为间接依赖下载下来,而devDependencies
不会
最后,与君共勉