Yarn Link 是如何幫助開發者對 NPM 包進行 Debug 的?
大家好,我是前端西瓜哥。最近在研究 React 源碼,用到了 yarn link 命令來鏈接兩個項目。
我對其底層原理產生了興趣,所以寫了這么一篇文章,希望能夠通過故事的形式,來讓大家理解 yarn link 的使用場景和用法。
另外 npm link 和 yarn link 的效果是相同的,下文就不提及 npm link 了。
有一天,小瓜維護的一個名為 xigua 的 NPM 包,被人提了 issue。小瓜看了下問題描述,憑著對項目的熟悉,他大概知道是哪里出了問題。
為了測試,小瓜搭建了一個 demo-project 項目,且這個項目通過 yarn add xiga 安裝了這個包,并在代碼中使用了它。
└── demo-project
└── node_modules
├── apple
└── xigua
├── old.js
└── package.json
理論上,小瓜去這個 demo-project 項目的 node_module/xigua 目錄下直接修改代碼就好了。
但不幸的是,里面的代碼是編譯出來的,無法直接修改。
小瓜于是跑到了 xigua-project 包的源碼項目中,運行了一個可以監聽源碼修改生成 npm 包內容的命令。小瓜修改了一處代碼,然后自動編譯到了 xigua-project/build/ 中。
└── xigua-project
└── build
└── xigua(編譯出來的文件夾)
├── fix.js
└── package.json
然后小瓜就復制編譯好的代碼,覆蓋掉原來的demo-project/node_module/xigua ,然后看看效果不對。小瓜發現不對,再改,然后再復制,一連重復了好幾次。
“我受不了了,得想個辦法。”小瓜說。每次編譯完都要手動進行復制操作,太搞人心態了。
機智的小瓜一番思考,最終想到了一個辦法。
- 將 demo-project 下的 xigua 依賴包刪除
- 然后創建一個 xigua 軟鏈接文件,鏈接到 xigua-project 下的編譯文件夾(軟鏈接可以理解為快捷方式文件,可以將文件位置重定向)。
├── demo-project
│ └── node_modules
│ ├── apple
│ └── xigua(重定向) -> /xigua/build/node_modules/xigua
└── xigua-project
└── build
└── xigua(被鏈接的位置)
├── fix.js
└── package.json
利用軟鏈接,我們將兩個項目關聯了起來。
yarn link
此時,舍友小潤抱著他的猹路過了,猹是他的貓的名字。
小瓜正對自己的奇思妙想沾沾自喜,立馬向小潤吹噓起來。
小潤:“這個需求,包管理器是有相關命令支持的。”
小瓜:“居然有!展開說說怎么用。”
小潤于是講解了起來。
其實很簡單,我們進入到 xigua/build/xigua 目錄下,執行 yarn link。
$ yarn link
yarn link v1.22.17
success Registered "xigua".
info You can now run `yarn link "xigua"` in the projects where you want to use this package and it will be used instead.
? Done in 0.01s.
這樣,包管理工具就會 在全局注冊一個名為 xiuga 的鏈接。
具體就是創建一個 xigua 軟鏈接文件,指向這個 xigua 目錄。在 macOS 中,是在 ~/.config/yarn/link/xigua 目錄下。
鏈接指向如下:
~/.config/yarn/link/xigua -> /xigua-project/build/xigua
更準確來說,yarn link 是會從當前工作目錄往上找第一個有正確 package.json 文件的目錄,作為鏈接的對象,因為 npm 包里必須要有 package.json。
接下來我們再跑到 demo-project 項目的目錄下,執行 yarn link xigua。
$ yarn link xigua
yarn link v1.22.17
success Using linked package for "xigua".
? Done in 0.01s.
它會做兩個操作:
- 將 demo-project 下的 xigua 依賴包刪除。
- 然后創建一個 xigua 軟鏈接文件,鏈接到 yarn/link/xigua。形成 demo-project -> yarn/link -> xigua-project的鏈。
小瓜震驚了:“這操作不就和我的做法一樣嗎?不過多了一個 中間人 yarn”。
是的,但 yarn 更方便。
yarn unlink
你在 demo-project 測試完了,想要斷開鏈接,此時需要執行:
$ yarn unlink xigua
yarn unlink v1.22.17
success Removed linked package "xigua".
info You will need to run `yarn install --force` to re-install the package that was linked.
? Done in 0.01s.
斷開鏈接后,因為原來的包刪掉并換了個鏈接文件,所以我們需要再把這個包裝回來,需要執行 yarn install --force。
你說我刪除 node_modules,然后再執行 yarn 行不行。
可以,前提是你的 node_modules 沒有其他包的鏈接,否則的話會把其他包的鏈接也干掉。
如果要刪除全局的注冊的名為 xigua 的 link,需要進入到被鏈接的目錄下,執行 yarn unlink。
$ yarn unlink
yarn unlink v1.22.17
success Unregistered "xigua".
info You can now run `yarn unlink "xigua"` in the projects where you no longer want to use this package.
? Done in 0.01s.
結尾
yarn link 的作用是幫助我們調試開發的 NPM 包。
因為普通項目的依賴包安裝是從網絡下載安裝的,如果要使用本地編譯的 NPM 包,比較好的方式是刪掉依賴包,通過快捷方式來鏈接我們本地編譯包。
為了簡化這一流程,yarn link 出現了,通過中間者的形式,來實現快速地 link 和 unlink。