问题思考:
1. package-lock.json的意义?
2. npm 拉包机制和源码实现 ?
3. yarn?
4. package-lock.json有没有必要提交?
5. npmrc?
6. npx?
7. 还有 import 直接导入包的cnd地址 和 安装到本地有啥区别:(打包时候的vender 大小 和 是否在缓存获取的取舍)?
1. package-lock.json的意义 蹦到官网
This file is intended to be committed into source repositories, and serves various purposes:
1. Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
2. Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.
3. Facilitate greater visibility of tree changes through readable source control diffs.
4. Optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.
5. As of npm v7, lockfiles include enough information to gain a complete picture of the package tree, reducing the need to read package.json files, and allowing for significant performance improvements.
该文件旨在提交到源存储库中,并具有多种用途:
1. 描述一个依赖关系树的单一表示,这样可以确保队友,部署和持续集成安装完全相同的依赖关系。
2. 为用户提供一种工具,使其可以“时间旅行”到以前的状态, node_modules而不必提交目录本身。
3. 通过可读的源代码控制差异,提高树更改的可见性。
4. 通过允许npm跳过先前安装的程序包的重复元数据解析来优化安装过程。
5. 从npm v7开始,锁定文件包含足够的信息以获取软件包树的完整图片,从而减少了读取package.json 文件的需求并显着提高了性能。
2. npm 拉包机制和源码实现
来自拉勾教育,收费的那种0.0
2.1 npm install 之后执行了哪些步骤?
1. 检查并获取 npm 配置, 这里的优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件。
2. 检查项目中是否有 package-lock.json 文件。
3. 3.1 如果 有 ,则检查 package-lock.json 和 package.json 中声明的依赖是否一致:
a: 一致,直接使用 package-lock.json 中的信息,从缓存或网络资源中加载依赖;
b: 不一致,按照 npm 版本进行处理(不同 npm 版本处理会有不同,具体处理方式如图所示)。
3.2 如果 没有 ,则根据 package.json 递归构建依赖树。然后按照构建好的依赖树下载完整的依赖资源,在下载时就会检查是否存在相关资源缓存:
a: 存在,则将缓存内容解压到 node_modules 中;
b: 否则就先从 npm 远程仓库下载包,校验包的完整性,并添加到缓存,同时解压到 node_modules。
4. 生成 package-lock.json。
2.2 npm 缓存机制
1. 获取配置缓存的根目录:npm config get cache
2. 缓存目录的内容介绍: 打开_cacache文件后,可以看到三个目录content-v2, index-v5, tmp (空文件)。
2.1 content-v2 里面基本都是一些二进制文件。为了使这些二进制文件可读,我们把二进制文件的扩展名改为 .tgz,然后进行解压,得到的结果其实就是我们的 npm 包资源。
2.2 index-v5 文件中,这些内容是 content-v2 里文件的索引。
3. 缓存如何被利用:
3.1 当 npm install 执行时,通过
pacote
把相应的包解压在对应的 node_modules 下面。npm 在下载依赖时,先下载到缓存当中,再解压到项目 node_modules 下。
pacote
依赖
npm-registry-fetch
来下载包,
npm-registry-fetch
可以通过设置 cache 属性,在给定的路径下根据
IETF RFC 7234
生成缓存数据。
3.2 在每次安装资源时,根据 package-lock.json 中存储的 integrity、version、name 信息生成一个唯一的 key,这个 key 能够对应到 index-v5 目录下的缓存记录。如果发现有缓存资源,就会找到 tar 包的 hash,根据 hash 再去找缓存的 tar 包,并再次通过
pacote
把对应的二进制文件解压到相应的项目 node_modules 下面,省去了网络下载资源的开销。
注意,这里提到的缓存策略是从 npm v5 版本开始的。在 npm v5 版本之前,每个缓存的模块在 ~/.npm 文件夹中以模块名的形式直接存储,储存结构是:{cache}/{name}/{version}。
3. yarn 来自拉勾教育,收费的那种0.0
3.1 yarn的介绍
当 npm 还处在 v3 时期时,一个叫作 Yarn 的包管理方案横空出世。2016 年,npm 还没有 package-lock.json 文件,安装速度很慢,稳定性也较差,而 Yarn 的理念很好地解决了以下问题。
1. 确定性 :通过 yarn.lock 等机制,保证了确定性。即不管安装顺序如何,相同的依赖关系在任何机器和环境下,都可以以相同的方式被安装。(在 npm v5 之前,没有 package-lock.json 机制,只有默认并不会使用的 npm-shrinkwrap.json 。)
2. 采用模块扁平安装模式 :将依赖包的不同版本,按照一定策略,归结为单个版本,以避免创建多个副本造成冗余(npm 目前也有相同的优化)。
3. 网络性能更好 :Yarn 采用了请求排队的理念,类似并发连接池,能够更好地利用网络资源;同时引入了更好的安装失败时的重试机制。
4. 采用缓存机制,实现了离线模式 (npm 目前也有类似实现)。