بازگشت به وبلاگ

چگونه پروکسی را برای npm در صورت مسدود شدن registry تنظیم کنیم: آینه‌ها، .npmrc و دور زدن محدودیت‌ها

نحوه تنظیم پروکسی برای npm در صورت مسدود شدن رجیستری رسمی را بررسی می‌کنیم - از آینه‌ها تا پیکربندی .npmrc و سرورهای پروکسی شرکتی.

📅۳۱ تیر ۱۴۰۵
```html

npm-registry در دسترس نیست — و ساخت پروژه متوقف شده است. این وضعیت برای توسعه‌دهندگان در شبکه‌های شرکتی، مناطق با دسترسی محدود یا هنگام کار از طریق فایروال‌های سخت‌گیرانه آشناست. در این راهنما تمام روش‌های کارآمد را بررسی خواهیم کرد: از سوئیچ به آینه‌ها تا تنظیم دقیق پروکسی در .npmrc — تا npm install دوباره بدون خطا کار کند.

چرا npm registry مسدود می‌شود و در این صورت چه اتفاقی می‌افتد

registry رسمی npm در آدرس https://registry.npmjs.org قرار دارد. این یک CDN جهانی است، اما به دلایل مختلف ممکن است در دسترس نباشد و هر یک نیاز به رویکرد خاص خود دارد.

دلایل اصلی عدم دسترسی به registry

  • فایروال شرکتی — شرکت درخواست‌های مستقیم به مخازن خارجی را مسدود می‌کند و ترافیک را فقط از طریق سرور پروکسی داخلی مجاز می‌داند. این یک عمل استاندارد در بانک‌ها، نهادهای دولتی و شرکت‌های بزرگ IT است.
  • مسدودیت جغرافیایی یا محدودیت‌های منطقه‌ای — در برخی کشورها و مناطق، دسترسی به npmjs.org در سطح ارائه‌دهنده اینترنت یا فایروال دولتی محدود شده است.
  • شبکه اداری بدون دسترسی مستقیم به اینترنت — ماشین‌های کاری در بخش‌های ایزوله شبکه به منابع خارجی دسترسی مستقیم ندارند و تمام ترافیک از طریق دروازه شرکتی عبور می‌کند.
  • تونل VPN با پروکسی اجباری — VPN شرکتی تمام ترافیک را هدایت می‌کند و npm نمی‌تواند به طور مستقیم به registry دسترسی پیدا کند.
  • مشکلات با بازرسی SSL — پروکسی شرکتی ترافیک HTTPS را قطع کرده و گواهی‌ها را تغییر می‌دهد که باعث بروز خطاهایی مانند SELF_SIGNED_CERT_IN_CHAIN یا UNABLE_TO_VERIFY_LEAF_SIGNATURE می‌شود.

خطاهای رایج در صورت مسدود بودن registry

npm ERR! code ECONNREFUSED
npm ERR! errno ECONNREFUSED
npm ERR! network request to https://registry.npmjs.org/react failed

npm ERR! code ETIMEDOUT
npm ERR! network This is a problem related to network connectivity.

npm ERR! code CERT_HAS_EXPIRED
npm ERR! code SELF_SIGNED_CERT_IN_CHAIN

هر یک از این کدهای خطا به یک مشکل متفاوت اشاره دارد: ECONNREFUSED — اتصال توسط فایروال رد شده است، ETIMEDOUT — درخواست به هیچ جا نمی‌رود (بدون پاسخ مسدود شده است)، خطاهای گواهی — مشکل بازرسی SSL. درک علت به سرعت دامنه راه‌حل‌ها را محدود می‌کند.

آینه‌های npm registry: دور زدن سریع بدون پروکسی

ساده‌ترین راه برای دور زدن مسدودیت — سوئیچ کردن npm به آینه جایگزین registry است. آینه همان بسته‌ها را که در registry رسمی وجود دارد، دارد، اما در سرورها و دامنه‌های دیگر قرار دارد. این روش زمانی کار می‌کند که فقط دامنه registry.npmjs.org مسدود شده باشد، نه تمام ترافیک HTTPS.

آینه‌های محبوب npm

آینه URL ویژگی‌ها
Taobao / npmmirror https://registry.npmmirror.com همگام‌سازی هر 10 دقیقه، سرعت خوب از آسیا
آینه Yarn Berry https://registry.yarnpkg.com توسط تیم Yarn پشتیبانی می‌شود، با کلاینت npm سازگار است
Verdaccio (میزبان خود) http://localhost:4873 registry خصوصی با کش کردن، در شبکه‌های ایزوله کار می‌کند
Nexus Repository http://nexus.company.local/npm راه‌حل شرکتی، پروکسی و کش کردن بسته‌ها
JFrog Artifactory https://artifactory.company.com/npm سطح Enterprise، حسابرسی وابستگی‌ها، کنترل دسترسی

چگونه registry را تغییر دهیم

تغییر برای یک دستور (بدون تغییر تنظیمات جهانی):

# نصب یک‌باره از طریق registry جایگزین
npm install react --registry https://registry.npmmirror.com

# نصب به‌طور جهانی برای کاربر فعلی
npm config set registry https://registry.npmmirror.com

# بررسی registry فعلی
npm config get registry

# بازگشت به registry رسمی
npm config set registry https://registry.npmjs.org

نکته مهم: اگر شما در پروژه‌ای به آینه سوئیچ می‌کنید، بهتر است این را در فایل .npmrc در ریشه مخزن ثبت کنید — در این صورت تمام اعضای تیم به‌طور خودکار پیکربندی صحیح را هنگام کلون کردن پروژه دریافت خواهند کرد.

# .npmrc در ریشه پروژه
registry=https://registry.npmmirror.com

تنظیم پروکسی از طریق .npmrc: سینتکس کامل

زمانی که آینه کمک نمی‌کند (به عنوان مثال، تمام ترافیک HTTPS خارجی مسدود شده است)، باید به‌طور صریح آدرس سرور پروکسی را به npm بدهید. فایل .npmrc — فایل پیکربندی اصلی npm است و تنظیمات پروکسی در آن ذخیره می‌شود.

محل فایل‌های .npmrc

npm پیکربندی را در چندین مکان جستجو می‌کند — به ترتیب اولویت (از بالا به پایین):

  • پروژه‌ای/path/to/project/.npmrc — فقط به این پروژه اعمال می‌شود
  • کاربر~/.npmrc — برای کاربر فعلی سیستم اعمال می‌شود
  • جهانی$PREFIX/etc/npmrc — برای تمام نصب npm اعمال می‌شود
  • داخلی/path/to/npm/npmrc — تنظیمات پیش‌فرض خود npm

سینتکس تنظیم پروکسی در .npmrc

# پروکسی برای ترافیک HTTP
proxy=http://proxy.example.com:8080

# پروکسی برای ترافیک HTTPS (برای اکثر درخواست‌ها به registry استفاده می‌شود)
https-proxy=http://proxy.example.com:8080

# پروکسی با احراز هویت (نام کاربری:رمز عبور در URL)
proxy=http://username:[email protected]:8080
https-proxy=http://username:[email protected]:8080

# استثناها — آدرس‌هایی که پروکسی را دور می‌زنند
noproxy=localhost,127.0.0.1,internal.company.com

⚠️ مهم درباره پروکسی HTTPS

توجه داشته باشید: پارامتر https-proxy آدرس سرور پروکسی را مشخص می‌کند که از طریق آن npm درخواست‌های HTTPS را انجام می‌دهد. خود آدرس پروکسی می‌تواند با http:// شروع شود — این طبیعی است. بیشتر پروکسی‌های شرکتی اتصالات را از طریق HTTP می‌پذیرند، اما در عین حال می‌توانند HTTPS را از طریق روش CONNECT تونل کنند.

نصب پروکسی از طریق دستورات npm config

جایگزینی برای ویرایش دستی فایل — استفاده از دستور npm config set. این دستور به‌طور خودکار تنظیمات را در ~/.npmrc کاربر ذخیره می‌کند:

# نصب پروکسی
npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080

# بررسی تنظیمات پروکسی فعلی
npm config get proxy
npm config get https-proxy

# حذف تنظیمات پروکسی (بازگشت به اتصال مستقیم)
npm config delete proxy
npm config delete https-proxy

# مشاهده تمام پیکربندی npm
npm config list

پروکسی از طریق متغیرهای محیطی برای npm

npm به‌طور خودکار متغیرهای محیطی استاندارد سیستم را برای پروکسی می‌خواند. این در CI/CD، کانتینرهای Docker و سیستم‌هایی که پیکربندی در سطح محیط تعیین می‌شود، راحت است.

متغیرهای محیطی استاندارد

# Linux / macOS — تنظیم در جلسه فعلی
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=localhost,127.0.0.1

# نسخه‌های کوچک (npm هر دو را درک می‌کند)
export http_proxy=http://proxy.example.com:8080
export https_proxy=http://proxy.example.com:8080

# Windows (Command Prompt)
set HTTP_PROXY=http://proxy.example.com:8080
set HTTPS_PROXY=http://proxy.example.com:8080

# Windows (PowerShell)
$env:HTTP_PROXY = "http://proxy.example.com:8080"
$env:HTTPS_PROXY = "http://proxy.example.com:8080"

اولویت پیکربندی npm

مهم است که درک کنید npm از اولویت زیر برای تعیین پروکسی استفاده می‌کند (از بالا به پایین):

  1. پرچم‌های خط فرمان: --proxy http://...
  2. متغیرهای محیطی با پیشوند npm_config_: به عنوان مثال، npm_config_proxy
  3. پروژه‌ای .npmrc
  4. کاربر ~/.npmrc
  5. جهانی $PREFIX/etc/npmrc
  6. متغیرهای محیطی استاندارد HTTP_PROXY / HTTPS_PROXY

اگر پروکسی در .npmrc تنظیم شده باشد، اما متغیر محیطی به آدرس دیگری اشاره کند — .npmrc برنده خواهد بود. این یک دلیل رایج برای سردرگمی در سیستم‌های CI/CD است.

تنظیم در CI/CD (GitHub Actions، GitLab CI)

# GitHub Actions — اضافه کردن به بخش env job یا step
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      HTTP_PROXY: http://proxy.example.com:8080
      HTTPS_PROXY: http://proxy.example.com:8080
      NO_PROXY: localhost,127.0.0.1
    steps:
      - uses: actions/checkout@v3
      - run: npm install

# GitLab CI — در متغیرهای پروژه یا در .gitlab-ci.yml
variables:
  HTTP_PROXY: "http://proxy.example.com:8080"
  HTTPS_PROXY: "http://proxy.example.com:8080"

پروکسی شرکتی با احراز هویت و بازرسی SSL

سرورهای پروکسی شرکتی — پیچیده‌ترین حالت هستند. آن‌ها فقط ترافیک را هدایت نمی‌کنند، بلکه نیاز به احراز هویت دارند و اغلب بازرسی SSL (قطع و رمزگشایی ترافیک HTTPS) را نیز انجام می‌دهند. این باعث بروز خطاهای خاص گواهی می‌شود که npm به‌طور پیش‌فرض نمی‌تواند با آن‌ها کار کند.

پروکسی با احراز هویت NTLM/Basic

اگر پروکسی شرکتی نیاز به نام کاربری و رمز عبور (احراز هویت Basic) داشته باشد، می‌توان آن‌ها را مستقیماً در URL ارسال کرد. اما با احراز هویت NTLM (دامنه ویندوز) اوضاع پیچیده‌تر است — npm به‌طور بومی از NTLM پشتیبانی نمی‌کند. در این حالت از ابزار میانجی استفاده می‌شود.

# احراز هویت Basic — نام کاربری و رمز عبور در URL
npm config set proxy http://user:[email protected]:8080
npm config set https-proxy http://user:[email protected]:8080

# اگر رمز عبور شامل کاراکترهای خاص باشد — باید آن‌ها را URL-encode کنید
# @ → %40, # → %23, : → %3A
# مثال: رمز عبور "p@ss#word" → "p%40ss%23word"
npm config set proxy http://user:p%40ss%[email protected]:8080

برای احراز هویت NTLM از ابزار cntlm استفاده می‌شود — این ابزار به‌طور محلی اجرا می‌شود، درخواست‌های HTTP معمولی را می‌پذیرد و خود احراز هویت NTLM را با پروکسی شرکتی انجام می‌دهد. برای npm این به‌صورت یک پروکسی معمولی بدون احراز هویت به نظر می‌رسد:

# پس از تنظیم cntlm، آن در localhost:3128 گوش می‌دهد
npm config set proxy http://localhost:3128
npm config set https-proxy http://localhost:3128

حل مشکل بازرسی SSL

پروکسی‌های شرکتی با بازرسی SSL گواهی‌های سایت‌ها را با گواهی شرکتی خود جایگزین می‌کنند. npm زنجیره اعتماد را بررسی کرده و چنین گواهی‌هایی را رد می‌کند. سه رویکرد وجود دارد:

روش 1 (توصیه می‌شود): اضافه کردن گواهی CA شرکتی به گواهی‌های معتبر

# دریافت گواهی شرکتی از بخش IT (فایل .crt یا .pem)
# مشخص کردن آن در پیکربندی npm
npm config set cafile /path/to/corporate-ca.crt

# یا اضافه کردن چندین گواهی از طریق cafile
# می‌توان چندین CA را در یک فایل PEM ترکیب کرد

روش 2 (موقت، ناامن): غیرفعال کردن بررسی SSL

# فقط به عنوان یک راه‌حل موقت برای تشخیص استفاده کنید!
npm config set strict-ssl false

# یا برای یک دستور
npm install --legacy-peer-deps --no-strict-ssl

⚠️ هشدار امنیتی

پارامتر strict-ssl false بررسی گواهی‌های SSL را به‌طور کامل غیرفعال می‌کند. این اتصال را در برابر حملات MITM آسیب‌پذیر می‌کند. از این روش فقط برای تشخیص استفاده کنید، نه در production و نه به‌طور دائمی. راه‌حل صحیح — اضافه کردن گواهی CA شرکتی از طریق cafile است.

پروکسی SOCKS5 برای npm: تنظیم از طریق ابزارهای کمکی

npm به‌طور بومی فقط از پروکسی‌های HTTP/HTTPS پشتیبانی می‌کند. اگر شما یک پروکسی SOCKS5 دارید (به عنوان مثال، از ارائه‌دهنده پروکسی‌های مسکونی)، نمی‌توان آن را به‌طور مستقیم در پیکربندی npm مشخص کرد. به یک لایه میانجی نیاز است — ابزاری که درخواست‌های HTTP را از npm می‌پذیرد و آن‌ها را از طریق SOCKS5 هدایت می‌کند.

روش 1: proxychains (Linux/macOS)

# نصب proxychains
# Ubuntu/Debian:
sudo apt-get install proxychains4

# macOS:
brew install proxychains-ng

# پیکربندی /etc/proxychains4.conf
[ProxyList]
socks5 proxy.example.com 1080 username password

# اجرای npm از طریق proxychains
proxychains4 npm install

روش 2: تبدیل‌کننده محلی HTTP به SOCKS5

ابزار privoxy یا polipo یک پروکسی HTTP محلی ایجاد می‌کند که ترافیک را از طریق SOCKS5 تونل می‌کند. پس از راه‌اندازی، npm یک پروکسی HTTP معمولی را در localhost می‌بیند:

# نصب privoxy
sudo apt-get install privoxy  # Ubuntu/Debian
brew install privoxy          # macOS

# اضافه کردن به پیکربندی /etc/privoxy/config:
forward-socks5 / proxy.example.com:1080 .

# Privoxy به‌طور پیش‌فرض در localhost:8118 گوش می‌دهد
# مشخص کردن npm برای استفاده از این آدرس:
npm config set proxy http://localhost:8118
npm config set https-proxy http://localhost:8118

روش 3: تونل SSH به عنوان پروکسی SOCKS5

اگر به یک سرور از راه دور با اینترنت باز دسترسی دارید، می‌توانید یک تونل SOCKS5 SSH ایجاد کرده و ترافیک npm را از طریق آن هدایت کنید. این به‌ویژه هنگام کار از شبکه شرکتی با دسترسی محدود راحت است:

# ایجاد تونل SOCKS5 SSH در پورت محلی 1080
ssh -D 1080 -f -C -q -N [email protected]

# سپس از privoxy یا proxychains برای تبدیل به HTTP استفاده کنید
# یا مستقیماً از طریق متغیر محیطی (Node.js از طریق برخی کتابخانه‌ها SOCKS را درک می‌کند)

# جایگزین — استفاده از curl به عنوان تست:
curl --socks5 localhost:1080 https://registry.npmjs.org/react/latest

registry خصوصی خود به عنوان جایگزینی برای پروکسی

در محیط‌های شرکتی و ایزوله، اغلب بهترین راه‌حل این است که به‌جای تنظیم پروکسی برای هر توسعه‌دهنده، یک npm-registry خصوصی درون شبکه راه‌اندازی کنید. این registry بسته‌ها را از npmjs.org عمومی کش کرده و آن‌ها را از شبکه داخلی ارائه می‌دهد. توسعه‌دهندگان به دسترسی به اینترنت نیاز ندارند — همه چیز از طریق registry محلی کار می‌کند.

Verdaccio: شروع سریع در 10 دقیقه

Verdaccio — یک npm-registry متن‌باز با پشتیبانی از پروکسی و کش کردن. به‌عنوان یک بسته npm نصب می‌شود و به‌عنوان یک سرویس جداگانه کار می‌کند:

# نصب Verdaccio به‌طور جهانی
npm install -g verdaccio

# راه‌اندازی (به‌طور پیش‌فرض در http://localhost:4873 گوش می‌دهد)
verdaccio

# تنظیم npm برای استفاده از registry محلی
npm config set registry http://localhost:4873

# انتشار بسته‌ها در registry محلی
npm adduser --registry http://localhost:4873
npm publish --registry http://localhost:4873

پیکربندی Verdaccio (~/.config/verdaccio/config.yaml) اجازه می‌دهد تا پروکسی‌کردن از طریق پروکسی خارجی برای بارگیری بسته‌ها از npmjs.org تنظیم شود:

# config.yaml — تنظیم uplink با پروکسی
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
    # اگر Verdaccio خود در پشت پروکسی باشد:
    agent_options:
      http_proxy: http://proxy.company.com:8080
      https_proxy: http://proxy.company.com:8080
      no_proxy: localhost,127.0.0.1

packages:
  '@*/*':
    access: $all
    publish: $authenticated
    proxy: npmjs
  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs

مقایسه راه‌حل‌ها برای محیط‌های ایزوله

راه‌حل پیچیدگی کش کردن مناسب برای
آینه (npmmirror) پایین خیر مسدودیت جغرافیایی، دسترسی کند به npmjs.org
پروکسی HTTP در .npmrc پایین خیر شبکه شرکتی با پروکسی HTTP
SOCKS5 + proxychains متوسط خیر پروکسی‌های مسکونی/موبایل، VPN
Verdaccio متوسط بله تیم‌ها، شبکه‌های ایزوله، CI/CD
Nexus / Artifactory بالا بله Enterprise، حسابرسی وابستگی‌ها

تشخیص و رفع خطاهای رایج

حتی پس از تنظیم صحیح پروکسی، ممکن است مشکلاتی پیش بیاید. در اینجا یک رویکرد سیستماتیک برای تشخیص و فهرستی از رایج‌ترین خطاها و راه‌حل‌های آن‌ها آورده شده است.

مرحله 1: بررسی پیکربندی فعلی npm

# نمایش تمام تنظیمات npm (شامل پروکسی)
npm config list

# نمایش فقط تنظیمات پروکسی
npm config get proxy
npm config get https-proxy
npm config get registry
npm config get strict-ssl

# فعال کردن خروجی دقیق برای تشخیص
npm install react --verbose
npm install react --loglevel verbose

مرحله 2: بررسی دسترسی به registry به‌طور مستقیم

# بررسی دسترسی به registry از طریق curl
curl -v https://registry.npmjs.org/react/latest

# بررسی از طریق پروکسی
curl -v --proxy http://proxy.example.com:8080 https://registry.npmjs.org/react/latest

# بررسی ping (همیشه برای HTTPS اطلاعاتی نیست)
ping registry.npmjs.org

# بررسی حل DNS
nslookup registry.npmjs.org

خطاهای رایج و راه‌حل‌های آن‌ها

خطا علت راه‌حل
ECONNREFUSED پروکسی اتصالات را نمی‌پذیرد یا پورت نادرست است بررسی آدرس و پورت پروکسی، دسترسی به سرور پروکسی
ETIMEDOUT درخواست توسط فایروال بدون پاسخ مسدود شده است تنظیم پروکسی یا سوئیچ به آینه
SELF_SIGNED_CERT بازرسی SSL پروکسی شرکتی اضافه کردن CA شرکتی از طریق cafile
407 Proxy Auth پروکسی نیاز به احراز هویت دارد اضافه کردن نام کاربری:رمز عبور به URL پروکسی
ENOTFOUND DNS نام registry یا پروکسی را حل نمی‌کند بررسی تنظیمات DNS، استفاده از IP به جای نام
E403 Forbidden پروکسی درخواست‌ها به npmjs.org را مسدود می‌کند استفاده از آینه یا تماس با مدیر شبکه

بازنشانی تمام تنظیمات پروکسی

# حذف تمام تنظیمات پروکسی از پیکربندی کاربر
npm config delete proxy
npm config delete https-proxy
npm config delete noproxy

# بازنشانی registry به رسمی
npm config set registry https://registry.npmjs.org

# بازگرداندن strict-ssl (اگر غیرفعال شده بود)
npm config set strict-ssl true

# بررسی پیکربندی نهایی
npm config list

کار با pnpm و Yarn در صورت مسدود بودن registry

اگر از مدیران بسته جایگزین استفاده می‌کنید، تنظیم پروکسی به‌طور مشابه به نظر می‌رسد، اما سینتکس کمی متفاوت است:

# pnpm — از همان .npmrc که npm استفاده می‌کند، استفاده می‌کند
# همچنین می‌توان از طریق pnpm config تنظیم کرد:
pnpm config set proxy http://proxy.example.com:8080
pnpm config set https-proxy http://proxy.example.com:8080
pnpm config set registry https://registry.npmmirror.com

# Yarn Classic (v1) — فایل .yarnrc خود
yarn config set proxy http://proxy.example.com:8080
yarn config set https-proxy http://proxy.example.com:8080
yarn config set registry https://registry.npmmirror.com

# Yarn Berry (v2+) — فایل .yarnrc.yml
# httpProxy: "http://proxy.example.com:8080"
# httpsProxy: "http://proxy.example.com:8080"
# npmRegistryServer: "https://registry.npmmirror.com"

تنظیم پروکسی برای بسته‌های خاص scoped

گاهی اوقات نیاز است که از registry‌های مختلف برای بسته‌های مختلف استفاده کنید: به عنوان مثال، بسته‌های عمومی را از npmjs.org رسمی بگیرید، در حالی که بسته‌های شرکتی @company/* را از Nexus داخلی بگیرید. این از طریق registry خاص scope در .npmrc تنظیم می‌شود:

# .npmrc — registry‌های مختلف برای scope‌های مختلف
registry=https://registry.npmjs.org

# بسته‌های شرکتی @company از طریق Nexus داخلی
@company:registry=http://nexus.company.local/repository/npm-hosted/

# بسته‌های @myorg از طریق Verdaccio
@myorg:registry=http://localhost:4873/

# احراز هویت برای registry خاص
//nexus.company.local/repository/npm-hosted/:_authToken=YOUR_TOKEN_HERE

نتیجه‌گیری و توصیه‌های نهایی

در این مقاله، روش‌های مختلفی برای تنظیم پروکسی برای npm در صورت مسدود بودن registry بررسی شد. با استفاده از آینه‌ها، تنظیمات پروکسی در .npmrc و استفاده از ابزارهای کمکی، می‌توانید به راحتی به بسته‌های npm دسترسی پیدا کنید. همچنین، در صورت بروز مشکلات، مراحل تشخیص و رفع خطاها ارائه شد.

```