>[success] # npm -- install 安装流程
~~~
1.npm install 执行之后,首先,检查并获取 npm 配置,这里的优先级为:项目级的
.npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的
.npmrc 文件。然后检查项目中是否有 package-lock.json 文件。
~~~
* 无 lock 文件:
* 从 npm 远程仓库获取包信息
* 根据 package.json 构建依赖树,构建过程:
* 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node\_modules 根目录。
* 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node\_modules 下放置该模块。
* 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包
* 在缓存中依次查找依赖树中的每个包
* 不存在缓存:
* 从 npm 远程仓库下载包
* 校验包的完整性
* 校验不通过: 重新下载
* 校验通过:
* 将下载的包复制到 npm 缓存目录
* 将下载的包按照依赖结构解压到 node\_modules
* 存在缓存:
* 将缓存按照依赖结构解压到 node\_modules
* 将包解压到 node\_modules
* 生成 lock 文件
* 如图
![](https://img.kancloud.cn/5a/56/5a56994219db210597aef684b2bcf363_826x649.png)
>[info] ## 什么是.npmrc
~~~
1.'.npmrc文件',就是npm的配置文件。修改配置文件 -- 'npm config edit',在弹出的界面
上,修改.npmrc文件后,保存即可
2.'.npmrc 文件' 位置
2.1.每个项目的配置文件 -- (/path/to/my/project/.npmrc)
项目里面如果和package.json同级存放了这个.npmrc
2.2.每个用户的配置文件 -- (~/.npmrc)
通过 'npm config ls -l' 指令找到'userconfig'字段看到具体位置,或者'npm config get userconfig'
2.3.全局配置文件 -- ($PREFIX/etc/npmrc)
通过 'npm config ls -l' 指令找到'globalconfig'字段看到具体位置,或者'npm config get globalconfig'
2.4.npm 内置配置文件 -- (/path/to/npm/npmrc) 就是全局'node_modules'下的npm里面
3.'.npmrc配置文件'中字段解释'https://www.npmjs.cn/misc/config/'
4.指令配置'https://docs.npmjs.com/cli/v7/commands/npm-config'
~~~
>[info] ## 缓存
~~~
1.在执行 'npm install' 或 'npm update'命令下载依赖后,除了将依赖包安装在
'node_modules' 目录下外,还会在本地的缓存目录缓存一份。查看缓存地址的指令:
'npm config get cache'
2.'cache'文件打开 可以看到三个文件 'content-v2' 、'index-v5'、 'tmp'
2.1.'content-v2'目录用于存储'tar'包的缓存,里面基本都是一些二进制文件,想具体看懂
文件到底是什么,将这些二进制文件的扩展名改为 '.tgz',然后进行解压,得到的结果其实
就是我们的 npm 包资源
2.2.'index-v5'目录用于存储'tar'包的'hash',这些内容就是 content-v2 里文件的索引
3.找到缓存文件。这里我在项目中安装一个'sass-loader',得到了'package-lock.json'
文件找到'sass-loader对应resolved字段',这里我是通过linux指令的文件查找,
(win没研究明白),通过在'index-v5'文件找到存储'tar'包的'hash'
' grep "https://registry.npmjs.org/sass-loader/-/sass-loader-12.1.0.tgz" -r index-v5'
在找到对应文件内容中搜索字段'_shasum',将这段vaule 在'content-v2 ' 文件搜索
举个例子上面的 _shasum 属性 6926d1b194fbc737b8eed513756de2fcda7ea408 即为 tar
包的 hash, hash的前几位 6926 即为缓存的前两层目录,文件目录如下
'content-v2/69/26/d1b194fbc737b8eed513756de2fcda7ea408'
既可以找到缓存的压缩包文件
~~~
* cache 结构目录
![](https://img.kancloud.cn/43/0a/430ad9d8e597e8911e95d21ce764f462_195x121.png)
* resolved字段
![](https://img.kancloud.cn/fd/e8/fde8a67786ac32626ffaf721e823e587_804x306.png)
* index-v5 文件
![](https://img.kancloud.cn/62/0f/620f9ab0e998b1ff3d5351d2acb5432e_1861x249.png)
>[danger] ##### 通过npm info 找shasum
~~~
1.在对应项目下输入'npm info 查看的包名'
~~~
![](https://img.kancloud.cn/1f/0c/1f0cfb6cc5a0f57b031b3347ab560413_1038x609.png)
>[danger] ##### 整体流程
当 npm install 执行时,通过[pacote](https://www.npmjs.com/package/pacote)把相应的包解压在对应的 node\_modules 下面。npm 在下载依赖时,先下载到缓存当中,再解压到项目 node\_modules 下。pacote 依赖[npm-registry-fetch](https://github.com/npm/npm-registry-fetch#npm-registry-fetch)来下载包,npm-registry-fetch 可以通过设置 cache 属性,在给定的路径下根据[IETF RFC 7234](https://datatracker.ietf.org/doc/rfc7234/)生成缓存数据。
接着,在每次安装资源时,根据 package-lock.json 中存储的 integrity、version、name 信息生成一个唯一的 key,这个 key 能够对应到 index-v5 目录下的缓存记录。如果发现有缓存资源,就会找到 tar 包的 hash,根据 hash 再去找缓存的 tar 包,并再次通过[pacote](https://www.npmjs.com/package/pacote)把对应的二进制文件解压到相应的项目 node\_modules 下面,省去了网络下载资源的开销。
>[danger] ##### 缓存参考的文章
[npm缓存现在是怎么做的?细节一定必读](https://www.zhihu.com/question/305539244)
>[info] ## 参考文章
[npm基本用法及原理(10000+) - 漫漫字节|漫漫编程 (mmbyte.com)](https://www.mmbyte.com/article/185966.html)
[前端工程化 - 剖析npm的包管理机制 (juejin.cn)](https://juejin.cn/post/6844904022080667661#heading-56)
[npm及.npmrc文件](https://blog.csdn.net/yexudengzhidao/article/details/109702948)
[链接](https://kaiwu.lagou.com/course/courseInfo.htm?courseId=584#/detail/pc?id=5906)
- 工程化 -- Node
- vscode -- 插件
- vscode -- 代码片段
- 前端学会调试
- 谷歌浏览器调试技巧
- 权限验证
- 包管理工具 -- npm
- 常见的 npm ci 指令
- npm -- npm install安装包
- npm -- package.json
- npm -- 查看包版本信息
- npm - package-lock.json
- npm -- node_modules 层级
- npm -- 依赖包规则
- npm -- install 安装流程
- npx
- npm -- 发布自己的包
- 包管理工具 -- pnpm
- 模拟数据 -- Mock
- 页面渲染
- 渲染分析
- core.js && babel
- core.js -- 到底是什么
- 编译器那些术语
- 词法解析 -- tokenize
- 语法解析 -- ast
- 遍历节点 -- traverser
- 转换阶段、生成阶段略
- babel
- babel -- 初步上手之了解
- babel -- 初步上手之各种配置(preset-env)
- babel -- 初步上手之各种配置@babel/helpers
- babel -- 初步上手之各种配置@babel/runtime
- babel -- 初步上手之各种配置@babel/plugin-transform-runtime
- babel -- 初步上手之各种配置(babel-polyfills )(未来)
- babel -- 初步上手之各种配置 polyfill-service
- babel -- 初步上手之各种配置(@babel/polyfill )(过去式)
- babel -- 总结
- 各种工具
- 前端 -- 工程化
- 了解 -- Yeoman
- 使用 -- Yeoman
- 了解 -- Plop
- node cli -- 开发自己的脚手架工具
- 自动化构建工具
- Gulp
- 模块化打包工具为什么出现
- 模块化打包工具(新) -- webpack
- 简单使用 -- webpack
- 了解配置 -- webpack.config.js
- webpack -- loader 浅解
- loader -- 配置css模块解析
- loader -- 图片和字体(4.x)
- loader -- 图片和字体(5.x)
- loader -- 图片优化loader
- loader -- 配置解析js/ts
- webpack -- plugins 浅解
- eslit
- plugins -- CleanWebpackPlugin(4.x)
- plugins -- CleanWebpackPlugin(5.x)
- plugin -- HtmlWebpackPlugin
- plugin -- DefinePlugin 注入全局成员
- webapck -- 模块解析配置
- webpack -- 文件指纹了解
- webpack -- 开发环境运行构建
- webpack -- 项目环境划分
- 模块化打包工具 -- webpack
- webpack -- 打包文件是个啥
- webpack -- 基础配置项用法
- webpack4.x系列学习
- webpack -- 常见loader加载器
- webpack -- 移动端px转rem处理
- 开发一个自己loader
- webpack -- plugin插件
- webpack -- 文件指纹
- webpack -- 压缩css和html构建
- webpack -- 清里构建包
- webpack -- 复制静态文件
- webpack -- 自定义插件
- wepack -- 关于静态资源内联
- webpack -- source map 对照包
- webpack -- 环境划分构建
- webpack -- 项目构建控制台输出
- webpack -- 项目分析
- webpack -- 编译提速优护体积
- 提速 -- 编译阶段
- webpack -- 项目优化
- webpack -- DefinePlugin 注入全局成员
- webpack -- 代码分割
- webpack -- 页面资源提取
- webpack -- import按需引入
- webpack -- 摇树
- webpack -- 多页面打包
- webpack -- eslint
- webpack -- srr打包后续看
- webpack -- 构建一个自己的配置后续看
- webpack -- 打包组件和基础库
- webpack -- 源码
- webpack -- 启动都做了什么
- webpack -- cli做了什么
- webpack - 5
- 模块化打包工具 -- Rollup
- 工程化搭建代码规范
- 规范化标准--Eslint
- eslint -- 扩展配置
- eslint -- 指令
- eslint -- vscode
- eslint -- 原理
- Prettier -- 格式化代码工具
- EditorConfig -- 编辑器编码风格
- 检查提交代码是否符合检查配置
- 整体流程总结
- 微前端
- single-spa
- 简单上手 -- single-spa
- 快速理解systemjs
- single-sap 不使用systemjs
- monorepo -- 工程
- Vue -- 响应式了解
- Vue2.x -- 源码分析
- 发布订阅和观察者模式
- 简单 -- 了解响应式模型(一)
- 简单 -- 了解响应式模型(二)
- 简单 --了解虚拟DOM(一)
- 简单 --了解虚拟DOM(二)
- 简单 --了解diff算法
- 简单 --了解nextick
- Snabbdom -- 理解虚拟dom和diff算法
- Snabbdom -- h函数
- Snabbdom - Vnode 函数
- Snabbdom -- init 函数
- Snabbdom -- patch 函数
- 手写 -- 虚拟dom渲染
- Vue -- minVue
- vue3.x -- 源码分析
- 分析 -- reactivity
- 好文
- grpc -- 浏览器使用gRPC
- grcp-web -- 案例
- 待续