先辨認 npm 安裝逾時發生在哪一段

Clash 開著時 npm 安裝一直逾時,不一定代表套件來源故障,也不必一開始就把 registry 換成其他鏡像。一次 npm install 可能先向套件註冊表查詢中繼資料,再下載套件壓縮檔;套件相依項目多時,還會連線到多個主機。只要其中一段連線沒有走到預期的代理出口,畫面就可能停在 idealTree、fetch 或下載進度,也可能最後才回報 ETIMEDOUT、ECONNRESET 或 ECONNREFUSED。

先記下逾時發生時的完整命令、錯誤碼與時間,不要只截取最後一行。若錯誤提到連線被拒絕,可能是 npm 指向了沒有啟動的本機代理埠;若錯誤是逾時,則可能是目標主機沒有被分流到合適的節點、直連品質不佳,或代理端點無法連線。若只有某一個套件失敗,還要留意套件的 tarball 網址與預設 registry 不一定是同一個主機;只測 registry 首頁能開,不代表實際套件檔也能下載。

排查時把問題分成三層比較容易:第一層是 Clash 本身是否正常運作,包括核心、目前選取的節點與代理模式;第二層是終端機裡的 Node.js/npm 是否真的使用到代理;第三層是 npm 設定的 registry、相依套件網址與分流規則是否相符。一次只改一層並重新測試,才能知道哪項調整確實改善了連線。

ℹ 先確認四件事:Clash 核心正在執行、目前節點可用、npm 使用的 registry 符合預期,以及終端機採用的代理設定沒有指向錯誤的連接埠。

檢查 Clash 模式、節點與分流規則

瀏覽器能正常上網,不表示 npm 一定走同一條連線。瀏覽器可能使用作業系統的系統代理,但終端機中的 Node.js 程序未必會自動讀取相同設定;如果你使用 TUN 模式,終端流量通常會由虛擬網路介面接管,但仍要確認 TUN 已啟用、路由沒有被其他 VPN 或防火牆攔截。若使用一般系統代理,則要確認客戶端已開啟系統代理,且你執行 npm 的終端機沒有沿用早前啟動時留下的環境變數。

在 Clash Verge、Clash Verge Rev、Mihomo 或其他相容客戶端中,先確認核心狀態正常,再檢查目前選中的策略組與節點。節點延遲測試成功只能表示探測網址可連線,不等於 npm 的 registry 或套件 CDN 一定可用。可以在 npm 重試時開啟連線紀錄,觀察 registry.npmjs.org 或錯誤訊息中出現的其他主機命中了哪條規則、最後交給哪個策略組,以及連線是否被重設或超時。

若紀錄顯示請求落入 MATCH、直連策略或不符合預期的規則,先檢查設定檔的規則順序。Clash 規則通常由上往下比對,較前面的廣泛規則可能先命中,使後面新增的單一網域規則沒有機會生效。相反地,如果請求已交給代理策略組,卻仍然失敗,就先測試另一個穩定節點,並確認該策略組沒有選到已失效的節點。不要為了解決一次安裝問題,就把所有流量長期改成全域代理;這會擴大影響範圍,也讓後續判斷更困難。

也要留意下載過程是否轉向其他主機。npm 顯示的 registry 是查詢套件資訊的入口,但套件檔可能由不同網域提供;某個套件甚至可能在其安裝流程中另外下載二進位檔。若 registry 請求有成功、tarball 卻卡住,請以錯誤訊息或 Clash 連線紀錄中的實際主機為依據補查,而不是只替 registry.npmjs.org 加一條規則。使用網域後綴規則時也要考慮涵蓋範圍,避免把不相關服務一併導入代理。

確認 npm registry 與代理設定

npm 的 registry 設定與 Clash 的代理設定是兩件不同的事。registry 決定 npm 向哪個套件服務查詢;代理設定則決定連線是否經過本機代理。先用下列指令檢視當前 registry 與 npm 所記錄的代理值:

npm config get registry
npm config get proxy
npm config get https-proxy
npm config list

預設 registry 常見為 https://registry.npmjs.org/。如果你曾設定其他鏡像,或專案有自己的 .npmrc,輸出結果可能與全域設定不同。npm 設定可能來自命令列、環境變數、專案目錄、使用者設定檔或全域設定;因此,僅檢查使用者層級的設定不一定能找到真正生效的值。執行 npm config list 時,注意設定來源提示,也檢查目前專案目錄是否有 .npmrc。

若決定讓 npm 明確使用 Clash 的 HTTP 代理,請先在客戶端確認實際監聽的 HTTP 或 mixed port,再將下方的連接埠替換成你的設定值。許多設定會使用 127.0.0.1 與本機連接埠,但不同客戶端、設定檔及使用者可能並不相同;不要只因為網路文章提到某個常見埠號,就直接照抄。

npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890

上例中的連接埠僅供說明,必須換成 Clash 實際提供的 HTTP/mixed port。這裡的 https-proxy 值仍可能使用 http://,因為它代表 npm 透過 HTTP 代理建立 HTTPS 連線,並不是把目標網站的 HTTPS 改成 HTTP。若你的本機入口是 SOCKS 代理,不要直接把 SOCKS 網址當成一般 HTTP 代理填入 npm;應使用 Clash 提供的 HTTP/mixed 入口,或依你採用的工具與 npm 版本確認相容方式。

如果 npm 內已留下失效代理值,先清除再測試系統代理或 TUN 是否足以處理終端流量:

npm config delete proxy
npm config delete https-proxy

另外檢查 shell 環境變數,例如 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 與 NO_PROXY。環境變數可能由終端設定檔、開發工具或啟動腳本帶入;即使你已清除 npm 設定,Node.js 程序仍可能讀取環境變數而使用舊代理。變數名稱的大小寫處理也可能因作業系統與程式而不同。若不確定來源,先在目前終端檢視,再開一個新的終端視窗比較;不要把含有帳號、密碼或內部代理主機的輸出貼到公開討論區。

⚠ 不要同時疊加多組設定:Clash 系統代理、npm 的 proxy、shell 的 HTTPS_PROXY 和第三方 VPN 可能互相覆蓋。每次測試只保留一種明確路徑,確認結果後再決定是否要長期固定設定。

動手測試:逐步定位是哪一段連線失敗

以下流程適合 Windows、macOS 與 Linux 上的 Node.js 專案。指令可在專案目錄執行;測試期間不要同時切換 Clash 節點、修改規則與更換 registry,否則就無法確定結果由哪項變更造成。若你正在使用公司或學校網路,也應先確認該網路的代理與套件來源規範,再調整用戶端設定。

  1. 記錄目前狀態。確認 Clash 核心正在執行、目前節點不是故障狀態,並記下目前代理模式、HTTP/mixed port、npm registry 與本機代理設定。先不要清除快取或刪除專案的鎖定檔,避免改變測試條件。
  2. 單獨測試 registry。在瀏覽器或命令列測試 registry 網址是否能連線。這一步只能判斷註冊表入口是否可達,不能代替實際套件安裝測試;若此處就失敗,先看 Clash 連線紀錄中請求是否命中預期策略。
  3. 讓 npm 顯示更多連線資訊。使用較詳細的輸出重跑原本失敗的安裝命令,並記錄第一個錯誤主機、錯誤碼與失敗階段。將失敗時間對照 Clash 紀錄,特別觀察請求命中的規則與出站策略,不要只憑進度條是否移動判斷。
  4. 只切換一項條件。若請求走直連,測試修正規則或暫時切到合適的代理策略;若請求已走代理但被拒絕,改測另一個可用節點;若本機代理連接埠拒絕連線,則先修正 npm 或環境變數中的連接埠。每次只改一項,再重試相同命令。
  5. 清除會干擾判斷的暫存因素。只有在日誌指向快取內容異常、或錯誤明確要求時,才考慮清理 npm 快取。快取清除無法修復錯誤代理、錯誤路由或失效節點;也不要把刪除 package-lock.json 當成通用排障方式,因為它可能改變依賴版本。

如果想用命令列確認某個 HTTPS 網址是否能透過 Clash 代理連線,可在支援相關選項的環境使用 curl 指定本機代理測試;網址與代理埠都應換成你實際使用的值。若指定代理時成功、未指定代理時失敗,問題較可能在終端沒有自動使用代理或分流路徑不一致;若兩種方式都失敗,則應繼續檢查節點、網路政策或目標服務狀態。這項測試不會證明所有 npm tarball 主機都可達,但能幫你確認基本代理入口是否工作。

curl -I --proxy http://127.0.0.1:7890 https://registry.npmjs.org/

測試完成後,可用 npm config get proxy 與 npm config get https-proxy 再核對一次設定。若只是臨時指定代理進行診斷,不要忘記恢復原有值;若你決定保留 npm 代理設定,則要確認 Clash 關閉後不會留下指向失效本機連接埠的設定,否則下次未啟動代理時,npm 仍可能無法連線。

依錯誤訊息修正,避免「換鏡像就算修好」

ETIMEDOUT 通常表示連線在期限內沒有完成,但原因可能是直連受阻、代理節點不穩、遠端主機延遲,或本機網路遭到限制。ECONNREFUSED 則更常見於本機代理埠沒有監聽、埠號填錯,或 Clash 核心尚未啟動。ECONNRESET 代表連線被中途重設,需比對是本機、代理端還是遠端在安裝流程的哪一段中止。這些錯誤碼只能提供線索,應搭配 npm 輸出與 Clash 紀錄判斷,不能單獨視為故障原因的定論。

若錯誤發生在憑證驗證階段,先確認系統日期時間正確、Node.js 版本與憑證環境正常,並檢查是否有公司安全設備或本機攔截軟體介入。不要為了「讓安裝先過」而關閉 TLS 憑證驗證;這會削弱套件下載的安全性,也可能掩蓋中間人攔截或錯誤代理設定。遇到代理需要帳密的環境時,也不要把憑證直接寫進公開的專案設定檔或命令歷史。

更換 registry 有時能改善特定網路的連線品質,但它不是代理設定的替代品。使用非預設來源前,先確認來源可信、套件版本與完整性資訊符合預期,並理解專案或團隊是否要求統一使用官方 registry。若使用鏡像後只改善中繼資料查詢、套件 tarball 仍在其他主機逾時,就要回到實際連線紀錄補查,而不是不斷改用新的來源。對團隊專案而言,尤其應避免在沒有記錄的情況下修改共用 .npmrc,以免其他開發者下載到不同來源或遭遇不同解析結果。

相較於只依賴瀏覽器系統代理、需要逐一猜測環境變數的手動設定,或單純更換 registry 來碰運氣,Clash V.CORE 可讓你從同一個客戶端管理代理狀態、檢查實際連線並依規則調整 npm 流量的出口;若你正想把本篇的檢查流程落實到日常開發環境,可以先前往下載,再依照自己的 npm registry 與本機代理埠完成測試。