﻿# 如何在 Windows 平台變更 Node.js / npm 全域模組的預設安裝路徑

由於 npm 本身的設計缺陷（直到 npm 3.x 才會改善），會導致安裝模組時，可能會因為特定模組用到相依模組而安裝非常多檔案與資料夾，而且資料夾的層級非常深，在 Mac OS X / Linux 環境下其實並不會有問題，但到了 Windows 環境下的問題可大了，因為 Windows 作業系統有路徑檔名的限制（完整的檔名必須少於 260 個字元，並且目錄名稱必須少於 248 個字元），即便到了 Windows 10 還是有這個限制存在，所以在 Windows 平台透過 npm 安裝套件時，經常會有「指定的路徑、檔名，或是兩者都太長」的錯誤發生，本篇文章將說明問題發生的原因與解決此問題的方法。

### 重現問題

你可以試試用 npm 安裝 [browser-sync](https://www.npmjs.com/package/browser-sync) 套件到全域模組中，如下指令：

```
npm install –g browser-sync
```

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/f26dd8512654bfed5c35-image_2720.png)

安裝的過程，你可能會遇到以下問題：

> 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\]

如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/4f410c804600c181cf0d-image_2721.png)

### 問題說明

你可以發現這段長長的紅字(錯誤訊息)已經明確提到了，在用 [MSBuild](https://msdn.microsoft.com/zh-tw/library/dd393574.aspx) 編譯一個 C++ 專案時，有一些編譯過程的物件檔無法被建立，因此導致這些 **原生的 Node.js 模組** ([node-gyp](https://github.com/nodejs/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 config 命令設定：
    
    ```
    npm config set prefix "C:\npm" -g
    ```
    
-   或直接用文字編輯器開啟 **C:\\Program Files\\nodejs\\node\_modules\\npm\\npmrc** 檔案
    
    這個檔案的預設內容為
    
    ```
    prefix=${APPDATA}\npm
    ```
    
    你只要將這個 prefix 設定值指向新的 npm 預設儲存路徑即可，例如：
    
    ```
    prefix=C:\npm
    ```
    

如此一來，基礎路徑變短了，整體的路徑就相對變短，編譯專案的成功率就會大幅成功，使用 npm 安裝套件的成功率也會大幅提高。

以我一開始的 [browser-sync](https://www.npmjs.com/package/browser-sync) 套件為例 ，原本無法順利安裝的套件，現在都可以順利的安裝成功了！ ^\_^

最後，可別忘了去修改 **PATH** 環境變數，將原本的 npm 安裝路徑變更到新指定的目錄下，因為你安裝的全域模組預設會在 prefix 目錄下建立一個相對應的 \*.cmd 批次檔，方便你在命令提示字元下執行 node.js 工具程式。

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a9ff0c4b151480a0dfaa-image_thumb_213.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/811becf4567b3876528a-image_2722.png)

**PATH** 環境變數設定畫面如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/1c7525f258fddb2b45c1-image_2723.png)

### 心得分享

由於前端工程師經常會需要安裝一些工具，而大部分的工具都會透過 Node.js 的 npm 進行安裝。不過，在 Windows 平台使用 npm 時有非常多陷阱，一不小心就會發生錯誤，這點讓許多身處 Windows 平台的前端工程師十分的困擾，這也是為什麼前端工程師大多使用 Mac 電腦的關係，使用 Mac 不僅僅是潮度加分，對於前端工程師來說，踩到地雷的機會也會少非常多。

不過，每每遇到困難，我就會有股衝動想釐清並解決問題，因為解決問題／釐清問題的過程，就是一種很好的學習方式，可以幫助我們釐清許多原本不知道的盲點。此外，畢竟需要在 Windows 平台的開發人員還是佔大多數，Node.js 既然是跨平台的，沒理由不能用，花時間下去研究，總是有方法解決的。

**相關連結**

-   [npm - Change default global installation directory for node.js modules in Windows? - Stack Overflow](http://stackoverflow.com/questions/19874582/change-default-global-installation-directory-for-node-js-modules-in-windows)
-   [Browsersync - Time-saving synchronised browser testing](http://www.browsersync.io/)
