npm 映象源怎麼設定:pnpm、yarn、bun 換源回切與裝包慢排查

部落格 / 開發工具

npm 映象源怎麼設定:pnpm、yarn、bun 換源回切與裝包慢排查

國內最常用的 npm 映象源地址是 https://registry.npmmirror.com,官方源是 https://registry.npmjs.org。舊的 registry.npm.taobao.org 早已停用,配置裡還寫著它的話,要儘快換掉。換源只解決“包的後設資料和 tarball 從哪下”,裝包慢的另一半原因往往在二進位制下載、lockfile 和本地網路,下面分開講。

先確認:現在用的是哪個源?

改之前先看清現狀,很多“換了源還是慢”的問題,其實是配置被別的地方覆蓋了。

npm config get registry
npm config list            # 看每一項來自哪個配置檔案
pnpm config get registry
yarn config get registry          # yarn v1
yarn config get npmRegistryServer # yarn Berry (v2+)

npm 的配置按優先順序從高到低是:命令列引數 > 環境變數(NPM_CONFIG_REGISTRY / npm_config_registry)> 專案裡的 .npmrc > 使用者目錄的 ~/.npmrc > 全域性配置。如果 CI 裡設定了環境變數,你在專案 .npmrc 裡寫什麼都不生效。

再順手查一下老域名有沒有殘留:

grep -rn "npm.taobao.org" ~/.npmrc ~/.yarnrc ~/.yarnrc.yml .npmrc .yarnrc .yarnrc.yml \
  package-lock.json yarn.lock 2>/dev/null

各個包管理器怎麼換源?

每種工具都給出三種寫法:全域性(隻影響你這臺機器)、專案級(跟著倉庫走,團隊成員一致)、單次(只這一條命令)。

npm

# 全域性:寫入 ~/.npmrc
npm config set registry https://registry.npmmirror.com

# 專案級:在專案根目錄建 .npmrc
echo "registry=https://registry.npmmirror.com" > .npmrc

# 單次
npm install --registry=https://registry.npmmirror.com

pnpm

pnpm 讀的是同一套 .npmrc,所以上面 npm 的專案級寫法對 pnpm 一樣有效。

pnpm config set registry https://registry.npmmirror.com   # 全域性
pnpm install --registry=https://registry.npmmirror.com    # 單次

yarn v1(Classic)

yarn v1 會讀 .npmrc,也有自己的 .yarnrc。

yarn config set registry https://registry.npmmirror.com   # 全域性,寫入 ~/.yarnrc
echo 'registry "https://registry.npmmirror.com"' > .yarnrc  # 專案級
yarn install --registry https://registry.npmmirror.com     # 單次

yarn Berry(v2 及以上)

Berry 不讀 .npmrc,配置項也換了名字,是 npmRegistryServer。

# 專案級:寫入當前目錄的 .yarnrc.yml
yarn config set npmRegistryServer https://registry.npmmirror.com

# 全域性:寫入 ~/.yarnrc.yml
yarn config set -H npmRegistryServer https://registry.npmmirror.com

# 單次:用環境變數
YARN_NPM_REGISTRY_SERVER=https://registry.npmmirror.com yarn install

bun

bun 推薦寫在 bunfig.toml,專案級放在倉庫根目錄,全域性放在 ~/.bunfig.toml:

[install]
registry = "https://registry.npmmirror.com"

較新的 bun 也會讀取 .npmrc 裡的 registry,並且認 NPM_CONFIG_REGISTRY 環境變數。團隊裡如果同時有人用 npm 和 bun,專案級 .npmrc 是最省事的共同配置。

對照表

工具專案級配置檔案配置項單次
npm.npmrcregistry--registry=
pnpm.npmrcregistry--registry=
yarn v1.yarnrc 或 .npmrcregistry--registry
yarn Berry.yarnrc.ymlnpmRegistryServerYARN_NPM_REGISTRY_SERVER=
bunbunfig.toml 或 .npmrcinstall.registryNPM_CONFIG_REGISTRY=

發包或要拿最新版本時,怎麼回切官方源?

映象站從官方同步,新發布的版本可能要等一段時間才出現。另外 npm publish、npm login 必須對官方源操作,映象不接受釋出。

# 永久回切
npm config set registry https://registry.npmjs.org
yarn config set npmRegistryServer https://registry.npmjs.org   # Berry

# 只在釋出時臨時指定
npm publish --registry=https://registry.npmjs.org

如果公司有私有源,可以只給某個 scope 單獨指定,不影響其他包:

# .npmrc
registry=https://registry.npmmirror.com
@your-company:registry=https://npm.your-company.example/

這裡的私有源地址只是示例。

為什麼換了源,CI 還在走舊地址?

原因通常在 lockfile。幾種 lockfile 記錄下載地址的方式不一樣:

  • package-lock.json(npm):每個包都寫了完整的 resolved URL。較新版本的 npm 有個 replace-registry-host 配置,預設值是 npmjs,意思是隻把 registry.npmjs.org 替換成你當前配置的源。如果 lockfile 裡寫的是 npmmirror 或老淘寶域名,npm 不會替換,CI 換回官方源也照樣去請求那個地址;老域名不可用時就直接失敗。
  • yarn.lock(v1):同樣寫了完整 resolved URL,老域名需要手動替換。
  • yarn Berry 的 yarn.lock、pnpm-lock.yaml:對預設 registry 上的包一般只記版本和 integrity,不寫完整地址,受影響小。
  • bun.lock:預設源的包通常不寫完整地址,有疑問就用 grep 查一下。

處理辦法有三種,按改動從小到大排:

# 1. 單次讓 npm 替換所有 resolved 的域名
npm ci --replace-registry-host=always

# 2. 把 lockfile 裡的老域名統一換成官方源(提交前看一眼 diff)
sed -i 's#https://registry.npm.taobao.org#https://registry.npmjs.org#g' package-lock.json

# 3. 刪掉 lockfile 重新生成(會順帶升級依賴,慎用)

我們的建議是:lockfile 裡統一保留官方源地址,各人的機器和 CI 透過 .npmrc 或環境變數決定實際走哪個源。這樣 lockfile 不隨個人習慣來回變,換源也不用改倉庫。integrity 校驗值和下載地址無關,映象下來的 tarball 內容一致就能透過。

為什麼 electron、sharp、playwright 換了源還是慢?

這類包的 npm 包本身很小,真正大的東西是在 postinstall 階段從另一個域名下載的:electron 從 GitHub Releases 拉二進位制,playwright 和 puppeteer 下載瀏覽器,老版本的 node-sass 下載編譯好的 binding。registry 換到哪裡,這些下載都不跟著走。

判斷方法:裝包時看日誌卡在哪一步。

npm install --foreground-scripts --loglevel=http

如果最後停在某個包的 postinstall,而且日誌裡出現 github.com、playwright 或 storage 相關的域名,那就是二進位制下載慢,不是 registry 慢。

常見的處理方式是透過環境變數把下載地址指向映象。npmmirror 提供了二進位制映象目錄(https://npmmirror.com/mirrors/),具體路徑以目錄裡實際存在的為準:

export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
export PLAYWRIGHT_DOWNLOAD_HOST="https://npmmirror.com/mirrors/playwright"
export SASS_BINARY_SITE="https://npmmirror.com/mirrors/node-sass"

幾點要注意:

  • 新版 sharp 的預編譯檔案改成以 @img/sharp-* 的 npm 包釋出,會隨 registry 一起走映象,一般不需要再配二進位制地址;老版本才需要。
  • 很多舊教程把 electron_mirror=... 這類鍵寫進 .npmrc。新版 npm 對不認識的配置項會給出警告,並提示以後的大版本里將不再支援。放在環境變數或 CI 的 env 裡更穩。
  • puppeteer 新版本的下載變數名和以前不同,以它的官方文件為準。
  • CI 裡如果不需要瀏覽器,可以用對應工具的“跳過下載”變數,直接省掉這一步。

慢到底慢在哪一層?一個判斷流程

換源是在解決“離源站太遠”的問題。如果慢在 DNS、代理或者本地網路,換源沒用。可以按下面的順序查:

第一步:分別測 registry 和二進位制下載域名的連線時間。

for u in https://registry.npmjs.org/react \
         https://registry.npmmirror.com/react \
         https://github.com; do
  curl -o /dev/null -s -w "$u\n  dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s ttfb=%{time_starttransfer}s total=%{time_total}s\n" "$u"
done

這幾個時間是累計值:dns 是域名解析,connect 到 TCP 建好,tls 到握手完成,ttfb 到伺服器返回第一個位元組。這個拆法和 cdnping 線上測速 的口徑一致:首頁對公共前端 CDN 分別測“首次連線”(含 DNS 與 TLS 握手)和“往返”(連線複用後 3 次請求的中位數)。在瀏覽器裡開啟測一遍,可以快速看出當前網路到境外和境內 CDN 節點的大致差距;各家 CDN 的橫向資料見 CDN 速度榜,測法見資料方法。關於這幾段時間分別代表什麼,可以參考 AI API 延遲拆解,原理和裝包是一樣的。

第二步:按結果對照處理。

現象大機率原因處理
dns 就要好幾秒DNS 解析慢或被汙染換 DNS,參考 DNS over HTTPS 配置指南
dns 正常,connect 很高到源站路由遠或丟包換映象源
映象 ttfb 正常但安裝仍慢卡在二進位制下載按上一節配置二進位制映象
時快時慢,部分請求超時代理規則或 IPv6 出口不一致查分流和雙棧
官方源和映象都慢本地網路本身有問題先做整體網路自檢

第三步:檢查代理。 npm 會讀 proxy、https-proxy 配置和 HTTPS_PROXY 環境變數。開著全域性代理時訪問國內映象,流量可能先繞到境外再回來,反而更慢。可以用 npm config get https-proxy 和 env | grep -i proxy 看有沒有殘留。分流規則怎麼判斷是否生效,見 國內網站如何看到你的真實 IP 和 分流原理。

如果系統同時有 IPv4 和 IPv6,而代理只接管了其中一個,就會出現“同一個命令有時快有時超時”,排查方法見 IPv6 代理不生效。

第四步:仍然說不清楚,就做一遍全鏈路檢查。 開發者網路自檢清單(2026 版) 把出口 IP、DNS、分流和測速串成了一個順序,適合在新機器或新 CI runner 上跑一遍。

換源前後的檢查表

  • npm config list 裡沒有 npm.taobao.org
  • 專案 .npmrc、.yarnrc.yml 或 bunfig.toml 和團隊約定一致
  • lockfile 裡沒有老域名;npm 專案的 resolved 統一用官方源
  • CI 的環境變數沒有覆蓋掉專案配置(或者覆蓋是有意的)
  • 釋出流程顯式寫了 --registry=https://registry.npmjs.org
  • electron、playwright 等二進位制下載地址放在環境變數裡,不放在 .npmrc
  • 用 curl 測過 registry 和二進位制域名的連線時間,確認慢在哪一層

小結

映象源本身只要改一行。換了還慢時,先用 curl 或線上測速把 DNS、連線、首位元組時間拆開,再按上面的表決定是改源、配二進位制映象,還是查代理和 DNS。