原来这些年我都理解错了dependencies和devDependencies

788 阅读4分钟

背景

在做公司内部lint包的时候,碰到了一个问题:Cannot find module 'xxxx'

image-20250116110357855.png

流程是这样的:

  1. npm-spec(公司内部lint包)的devDependencies下添加“eslint-config-alloy”:”catalog:eslint8”,不清楚“catalog:eslint8”的朋友可以看我这篇文章
  2. 在模板工程中安装 npm-spec,并在 .eslintrc.js 引入依赖

然后我在工程化项目的模板示例上验证是ok的,满怀期待的基于cli创建工程模板验证的时候,就出现了上面的问题,lint不生效(what?!震惊脸)

排错

因为我习惯了使用pnpm安装,所以第一反应就去看node_modules查看依赖,果然在依赖中没看到 eslint-config-alloy 的身影,大家也都知道pnpm解决了“幽灵依赖”的问题。

所以上面的问题也就容易推算出来,是因为eslint-config-alloy没有安装到宿主的依赖中去,那是什么原因导致了这个安装问题呢?下面就引出这期的主角:dependenciesdevDependencies

旧观念

dependencies 放的是生产依赖,所以需要打包到产物里的依赖都放dependencies

devDependencies 放的是非生产依赖,所以不需要打包到产物里的依赖都放devDependencies

也就是“dependencies === dist”这样的一个观念,这从业务开发的视角看似乎没啥问题

新观念

来自官方的解释:

image-20250116133847339.png

再结合实际安装依赖的表现,从npm包的开发者视角来看,“dependencies === dist”就有问题了

如果是使用npm安装依赖,因为是依赖是平铺的,所以在使用上没造成什么问题,但如果是使用pnpm安装依赖,那npm包的依赖管理就得慎重起来了

反思

为什么出现这种错误认知的观念呢?是因为没有经过系统性的学习,常常是这边学一点,那边看一点,不成体系的知识树导致我们在市场中的竞争力不强。

想要系统性的学习前端体系,可以来看一看大师课,大师课包含了…(虚晃一枪,没有广告)

image-20250116132959625.png

那如果在devDependencies安装生产所需的依赖,会不会打包到dist中去呢?做个验证:

image-20250116141624079.png

image-20250116141642749.png

很明显,哪怕依赖声明在devDependencies中,但在实际使用中是会打包近dist文件中的,所以只能是“dependencies == dist

梳理

好像有点乱,什么时候用dependencies?什么时候用devDependencies?这其实跟开发视角有关系

业务开发

因为最终作用生效的只有dist资源,不作为最终产物的上下游,所以理论上无所谓依赖放在哪个地方,但出于语义化和开发规范,需要打进dist的依赖应该加到dependencies

npm开发

因为最终作用生效的不仅是dist资源,还是作为构建最终产物的上游,dependencies的依赖会下载到宿主的node\_modules中,直接影响构建结果,所以对于npm包本身所需的依赖以及宿主没有且需要的依赖,需要放在dependencies中去

什么样的场景容易造成误判呢?下面举两个场景:

taro插件

taro使用插件是可以以Array<string>方式引入的,它底层是通过读取node_modules来查找依赖的

image-20250116144642560.png

如果你想基于taro的配置封装一个npm包出来,在里面做一些优化,可能用到了部分市场插件,这时候这些插件依赖应该声明在哪个地方?

lint配置

eslint部分配置也是通过字符串的形式引入的,同样,如果你想做一层封装,这些依赖应该声明在哪个地方?

image-20250116145541833.png

按业务开发视角来看很容易把这些依赖放在devDependencies中去,但如果宿主项目没有安装这些依赖,控制台就会报错。所以应该放在dependencies或者peerDependencies(感兴趣的可以自行搜下这个配置)

总结

dependencies == dist”,而不是“dependencies === dist”,且在做第三方库的时候需要重视你的依赖,因为dependencies依赖会作为间接依赖下载下来,而devDependencies不会

最后,与君共勉