pnpm 的 shamefully-hoist 選項

近期開始在專案中使用 pnpm 作為套件管理工具,關於 pnpm 的特色及優點不在此贅述, 本篇記錄在其中一項專案使用 pnpm 踩到的雷。

專案 A 依賴的套件 B,而套件 B 依賴了 webpack-dev-server,也就是 A -> B -> webpack-dev-server, 踩到的雷是在 A 當中運行 B 套件的指令時,會出現 webpack-dev-server 找不到的錯誤。

問題其實是 pnpm 的特色所導致,以往在使用 npmyarn 安裝套件時,所有依賴的套件(包括套件所依賴的套件) 會全部被安裝在 node_modules 目錄下,所以即使 webpack-dev-server 沒有被專案「直接依賴」一樣可以被調用到。

pnpm 則是將套件安裝在 node_modules/.pnpm 目錄下, 然後只把專案直接依賴的套件拉升到 node_modules 目錄下(用檔案連結的方式), 所以 node_module 看到的東西很乾淨,只會有專案直接依賴的套件,同樣地 node_modules/.bin 也只會有對應的可執行檔。 這樣的結果就是 webpack-dev-server 被安裝在 node_modules/.pnpm 目錄下,無法被調用到。

方法一:主動聲明 webpack-dev-server 為專案的直接依賴, 不傾向這個方法是希望專案能夠保持乾淨,不要有多餘的套件,還有未來需要持續追蹤版本號是否與 B 所依賴的版本號一致的問題。

方法二:使用 shamefully-hoist 選項, --shamefully-hoist 的意思是將所有套件都拉升到 node_modules 目錄下,也就是跟 yarnnpm 相同的行為。

參考:Does not install links to binaries of dependencies #3566

留言