BYChoo/blog

npm安装机制

BYChoo opened this issue · 0 comments

npm 的安装机制非常值得探究。Ruby 的 Gem、Python 的 pip 都是全局安装,但是 npm 的安装机制秉承了不同的设计哲学。

它会优先安装依赖包到当前项目目录,使得不同应用项目的依赖各成体系,同时还减轻了包作者的 API 兼容性压力,但这样做的缺陷也很明显:如果我们的项目 A 和项目 B,都依赖了相同的公共库 C,那么公共库 C 一般都会在项目 A 和项目 B 中,各被安装一次。这就说明,同一个依赖包可能在我们的电脑上进行多次安装

描述

npm install 执行之后,首先检查并获取npm配置,这里的优先级为:项目级的.npmrc文件>用户级的.npmrc文件>全局级的.npmrc文件>npm内置的.npmrc文件

然后检查项目中是否有package-lock.json文件
如果有,则检查package-lock.json和package.json中声明的以来是否一致
• 一致,直接使用package-lock.json中的信息,从缓存或网络资源中加载以来
• 不一致,按照npm版本进行处理

如果没有,则根据package.json递归构建依赖树。然后按照构建好的依赖树下载完整的依赖资源,在下载时就会检查是否存在相关的资源缓存

构建依赖树时,当前依赖项目不管其是直接以来还是子依赖的依赖,都应该按照扁平化原则,优先将其放置在node_module根目录。在这个过程中,遇到相同模块就判断已放置在依赖树中的模块版本是否符合新模块的版本范围,如果符合则跳过;不符合则在当前模块的node_modules下放置该模块

前端工程中,依赖嵌套依赖,一个中型项目中 node_moduels 安装包可能就已经是海量的了。如果安装包每次都通过网络下载获取,无疑会增加安装时间成本。对于这个问题,缓存始终是一个好的解决思路,我们接下来看看 npm 自己的缓存机制。

npm 缓存机制

对于一个依赖包的同一版本本地化缓存,是当代依赖包管理工具的一个常见设计。使用时要先执行一下命令:
npm config get cache

得到配置缓存的根目录在/Users/User/.npm当中。进入这个文件夹可以发现_cacache文件。事实上,在npm v5版本之后,混存数据均放在根目录中的_cache文件夹中

接下来打开_cacache文件,看看 npm 缓存了哪些东西,一共有 3 个目录:
• content-v2
• index-v5
• tmp

其中 content-v2 里面基本都是一些二进制文件。为了使这些二进制文件可读,我们把二进制文件的扩展名改为 .tgz,然后进行解压,得到的结果其实就是我们的 npm 包资源。

而 index-v5 文件中,我们采用跟刚刚一样的操作就可以获得一些描述性的文件,事实上这些内容就是 content-v2 里文件的索引。

npm 多源镜像和企业级部署私服原理

虽然 npm 并没有被屏蔽,但是下载第三方依赖包的速度依然较缓慢,这严重影响 CI/CD 流程或本地开发效率。部署镜像后,一般可以确保高速、稳定的 npm 服务,而且使发布私有模块更加安全。除此之外,审核机制也可以保障私服上的 npm 模块质量和安全。

那么,如何部署一个私有 npm 镜像呢?

现在社区上主要有 3 种工具来搭建 npm 私服:nexus、verdaccio 以及 cnpm。