[TOC]
>[success] # node_modules 層級
~~~
1.在 npm 的早期版本, npm 處理依賴的方式簡單粗暴,以'遞歸的形式',在npm3版本
后采用了'扁平結構'
~~~
>[danger] ##### npm2.x 版本node_modules 層級
~~~
1.執行?'npm install'?后,'npm' 根據 'dependencies' 和 'devDependencies' 屬性中指定的包
來確定第一層依賴,npm 2 會根據第一層依賴的子依賴,遞歸安裝各個包到子依賴的
'node_modules' 中,直到子依賴不再依賴其他模塊。執行完畢后,我們會看
到?'./node_modules'?這層目錄中包含有我們 'package.json' 文件中所有的依賴包,而這些
依賴包的子依賴包都安裝在了自己的 'node_modules' 中 結構目錄:
├── node_modules
│?? ├── A@1.0.0
│?? │?? └── node_modules
│?? │?? │?? └── D@1.0.0
│?? ├── B@1.0.0
│?? │?? └── node_modules
│?? │?? │?? └── D@2.0.0
│?? └── C@1.0.0
│?? │?? └── node_modules
│?? │?? │?? └── D@1.0.0
~~~
* 結構層級圖

~~~
1.果你依賴的模塊非常之多,你的 node_modules 將非常龐大,嵌套層級非常之深,
出現下圖的效果,并且也會導致接下來的問題
1.1.在不同層級的依賴中,可能引用了同一個模塊,導致大量冗余,舉個例子當我的 A,
B,C 三個包中有相同的依賴 D 時,執行?npm install?后,D 會被重復下載三次
1.2.在 Windows 系統中,文件路徑最大長度為260個字符,嵌套層級過深可能導致不可
預知的問題。
~~~

>[danger] ##### npm3.x 版本
~~~
1.npm3.x 版本后采用了扁平化的解決方案,把依賴以及依賴的依賴平鋪'node_modules'
文件夾下共享使用,npm 3 會遍歷所有的節點,逐個將模塊放在 'node_modules'的第一
層,當發現有重復模塊時,則丟棄, 如果遇到某些依賴版本不兼容的問題,則繼續采用
npm 2 的處理方式,前面的放在 'node_modules' 目錄中,后面的放在依賴樹中。
'過程說明':
下圖 'A','B' 都依賴'D(v0.0.1)'那么在安裝的時候將'A'的依賴包都平鋪到'node_modules',
即將'D(v0.0.1)'平鋪到了'node_modules' ,此時到了安裝B包發現B包依賴在
'node_modules' 根已經重復這時候就跳過了,但是安裝C的時候發現C也依賴'D'但是
依賴的版本不同,如果將C依賴的'D'放到'node_modules'根就因為重名問題覆蓋掉
此時解決方案就像'npm2.x'的時候就將C依賴的'D(v0.0.2)'安裝到了C的'node_modules'
下
~~~
* 如圖

* 是否解決npm2的 問題
~~~
1. 'A','B' 都依賴'D(v0.0.1)' ,'C' 依賴'D(v0.0.2)',如果先安裝C 此時 在安裝A,B時候由于
在安裝'C'的時候'D(v0.0.2)' 被平級安裝在'node_modules',因此'A','B''node_modules'
下都會有一個''D(v0.0.2)'
npm 3 并未完全解決冗余的問題,甚至還會帶來新的問題
~~~
* 如圖

>[info] ## 參考
[npm 依賴管理中被忽略的那些細節
](https://www.infoq.cn/article/qj3z2ygrzdgicqauaffn)
>[danger] ##### npm5.x 版本
~~~
1.從npm 5.x開始,安裝組織node_modules和npm 3.x一樣采用了扁平化的方式,最大的變化是增加了 package-lock.json 文件,npm 3.x有的問題他也有
2.package-lock.json 中已經緩存了每個包的具體版本和下載鏈接,不需要再去遠程倉庫
進行查詢,然后直接進入文件完整性校驗環節,減少了大量網絡請求
~~~
- 工程化 -- 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 -- 案例
- 待續