由於 npm 本身的設計缺陷(直到 npm 3.x 才會改善),會導致安裝模組時,可能會因為特定模組用到相依模組而安裝非常多檔案與資料夾,而且資料夾的層級非常深,在 Mac OS X / Linux 環境下其實並不會有問題,但到了 Windows 環境下的問題可大了,因為 Windows 作業系統有路徑檔名的限制(完整的檔名必須少於 260 個字元,並且目錄名稱必須少於 248 個字元),即便到了 Windows 10 還是有這個限制存在,所以在 Windows 平台透過 npm 安裝套件時,經常會有「指定的路徑、檔名,或是兩者都太長」的錯誤發生,本篇文章將說明問題發生的原因與解決此問題的方法。
重現問題
你可以試試用 npm 安裝 browser-sync 套件到全域模組中,如下指令:
npm install –g browser-sync
安裝的過程,你可能會遇到以下問題:
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(308,5): error MSB3491: 無法將行寫入檔案 "Release\obj\validation\validation.tlog\validation.lastbuildstate"。指定的路徑、檔名,或是兩者都太長。完整的檔名必須少於 260 個字元,並且目錄名稱必須少於 248 個字元。 [C:\Users\UserName\AppData\Roaming\npm\node_modules\browser-sync\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate\build\validation.vcxproj]
如下圖示:
問題說明
你可以發現這段長長的紅字(錯誤訊息)已經明確提到了,在用 MSBuild 編譯一個 C++ 專案時,有一些編譯過程的物件檔無法被建立,因此導致這些 原生的 Node.js 模組 (node-gyp) 無法成功被建置,所以產生了錯誤訊息。這裡你可以看到這個 C++ 專案檔 validation.vcxproj 位於 C:\Users\UserName\AppData\Roaming\npm\node_modules\browser-sync\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate\build\ 資料夾下,這可是多達 197 個字元的資料夾路徑,抵達上限的 248 個字元只差 51 個字元而已,但是專案編譯時所產生的檔案也不少,過程中有檔案無法輸出到 obj 資料夾時,就會遇到這個問題。
由於在 Windows 平台預設的 npm 全域模組安裝路徑為 %APPDATA%\npm 目錄,像我的使用者帳號為 UsernName 時,這個路徑就會是 C:\Users\UserName\AppData\Roaming\npm,因此可能會有人可以成功編譯該專案(因為使用者名稱較短,所以路徑也較短,只要編譯時產生的檔案路徑不要超出 Windows 作業系統的限制即可),但失敗的機率還是很大。
因此,我的解決辦法是:改變 Node.js / npm 全域模組的預設安裝路徑,也就是把 C:\Users\UserName\AppData\Roaming\npm 路徑縮短,成功率就提高了(但還是有可能會失敗)!
解決方法
變更預設的 npm 全域安裝路徑非常簡單,首先第一步是先準備好一個資料夾 ( C:\npm ),這裡你可以有兩個選項:
- 利用 mklink.exe 建立一個目錄連結,指令:mklink /d c:\npm "%appdata%\npm"
- 或是直接建立起一個實體資料夾,指令:mkdir c:\npm
然後修改 npm 的 npmrc 設定檔,這裡你一樣可以有兩個選項:
如此一來,基礎路徑變短了,整體的路徑就相對變短,編譯專案的成功率就會大幅成功,使用 npm 安裝套件的成功率也會大幅提高。
以我一開始的 browser-sync 套件為例 ,原本無法順利安裝的套件,現在都可以順利的安裝成功了! ^_^
最後,可別忘了去修改 PATH 環境變數,將原本的 npm 安裝路徑變更到新指定的目錄下,因為你安裝的全域模組預設會在 prefix 目錄下建立一個相對應的 *.cmd 批次檔,方便你在命令提示字元下執行 node.js 工具程式。
PATH 環境變數設定畫面如下圖示:
心得分享
由於前端工程師經常會需要安裝一些工具,而大部分的工具都會透過 Node.js 的 npm 進行安裝。不過,在 Windows 平台使用 npm 時有非常多陷阱,一不小心就會發生錯誤,這點讓許多身處 Windows 平台的前端工程師十分的困擾,這也是為什麼前端工程師大多使用 Mac 電腦的關係,使用 Mac 不僅僅是潮度加分,對於前端工程師來說,踩到地雷的機會也會少非常多。
不過,每每遇到困難,我就會有股衝動想釐清並解決問題,因為解決問題/釐清問題的過程,就是一種很好的學習方式,可以幫助我們釐清許多原本不知道的盲點。此外,畢竟需要在 Windows 平台的開發人員還是佔大多數,Node.js 既然是跨平台的,沒理由不能用,花時間下去研究,總是有方法解決的。
相關連結