如果
npm install -g
一切都不推荐,并且我不想链接各个模块,我可以将 <some project>/node_modules
符号链接到由多个项目共享的公共目录吗?
在 npm >= 7.21.0 中你不能。当您执行
npm install
时,npm 将删除一个名为 node_modules 的符号链接。
我使用yarn作为解决方法,它可以很好地处理符号链接的node_modules文件夹。
Node 可以完美地处理符号链接。如何实现这一目标将取决于您的一些目标。最重要的是:您希望其他从版本控制下载您的项目的开发人员获得什么体验?
在设计这种体验时,阅读 Node 模块加载算法非常有帮助,可以深入了解什么是可能的。
总的来说,我的建议是不要关心项目之间重复的依赖关系。 “修复”这个问题不值得付出维护成本,其中包括依赖关系僵局(子项目的需求冲突)以及在某些情况下需要自定义工具来解决您的自定义结构。
有了这个警告,我们该怎么做呢?最简单的方法是创建一个封装各种子项目的超级项目。子项目将有效继承超级项目的依赖关系。
superproject/
|-- node_modules/
| +-- socket.io/
|-- package.json
|-- subprojectA/
| |-- node_modules/
| | +-- browserify/
| |-- package.json
| +-- app/
| +-- client.js
+-- subprojectB/
|-- node_modules/
| +-- express/
|-- package.json
+-- lib/
+-- server.js
此结构按照您的预期工作,子项目中的文件可以
require()
自己的模块以及 superproject/node_modules
中的任何模块,但它们不会轻易 require()
其兄弟子项目中的模块(仍然可以通过显式路径执行此操作)。换句话说,client.js 可以在没有路径的情况下 require()
browserify 和 socket.io,但它需要使用 require()
express 的路径。
其中一个重要方面是
npm
会“查找”package.json 并在安装等时将 node_modules
目录中的模块作为该文件的同级来处理。这意味着您当前的工作目录需要是 superproject
才能在其中安装模块,除非您的子项目没有 package.json
文件。
我也注意到 npm 删除了我在 node_modules 中的符号链接。 我有很多使用节点构建的网站,这在写入磁盘方面是不切实际且浪费的。 所以我走极端,开始创建一个 tmpfs 挂载点,并将该目录绑定挂载到我的项目中。 但这在带宽方面似乎很浪费,所以我决定将分区安装到 /node_modules 并将其绑定安装到各个项目:
# extreme do not touch the disk mode:
#tmpfs /node_modules tmpfs noatime,nodev,nosuid,size=1400M 0 0
#
UUID="3848672deadbeef" /node_modules xfs rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota 0 0
/node_modules /mnt/example_sites/gatsby-theme-example/node_modules none bind 0 0
/node_modules /mnt/example_sites/example.com/node_modules none bind 0 0
/node_modules /mnt/example_sites/lovely_chickpea/node_modules none bind 0 0
加上额外的注意事项,我经常清除 node_modules 目录,通常是在家里,当我有良好的带宽时。 当我开始参与一个项目时,我总是会做一个
npm i
。 而且我不会同时处理多个项目,如果另一个项目的另一个 npm 更改了某些版本,同时在其他地方积极运行另一个会话,我预计会出现问题。
编辑:另一种可能的解决方案是将所有节点项目保留在 ZFS 卷中并打开重复数据删除。
现在继续讨论 ZFS 中的重复数据删除不值得、占用大量 RAM、危险将罗宾逊等的所有陈述。
但是,如果您有十个非常相似的节点项目,但需要通过轻微的依赖项更改来单独更新它们,并且能够同时处理所有项目,而无需擦除一些常见的 node_modules 目录并节省大量的磁盘写入,这可能非常值得。