>[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 文件
* 如圖

>[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 結構目錄

* resolved字段

* index-v5 文件

>[danger] ##### 通過npm info 找shasum
~~~
1.在對應項目下輸入'npm info 查看的包名'
~~~

>[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 -- 案例
- 待續