# Прокси в npm: proxy и https-proxy, приоритет .npmrc и ошибки установки

Source: https://ipvolt.com/ru/guides/npm-proxy-settings
Markdown: https://ipvolt.com/ru/guides/npm-proxy-settings.md
Language: ru

[ipvolt — главная](https://ipvolt.com/ru.md) / [Руководства](https://ipvolt.com/ru/guides.md) / Прокси в npm: proxy и https-proxy, приоритет .npmrc и ошибки установки

Интеграция
Опубликовано: 2026-10-13
9 мин чтения
Автор: ipvolt

Как настроить прокси в npm: proxy и https-proxy, конфликты .npmrc и окружения, проверка скачивания пакета, исправление маршрута и TLS без отключения проверки.

Когда npm ходит в реестр через прокси, проверьте **оба ключа — `proxy` и `https-proxy`**, выберите один утверждённый шлюз и убедитесь, что скачивается сам пакет, а не только отвечает реестр. Успешный `npm ping` ещё не доказывает, что установка сработает. На нашем стенде ping и метаданные пакета проходили, а запрос архива пакета (tarball) падал.

Наблюдения в этом руководстве сделаны на **npm 11.19.1, Node 26.10.0 и macOS 15.7.4** и записаны 12 октября 2026 года. Девять случаев маршрутизации и четыре проверки редактирования конфигурации соответствовали заявленным критериям приёмки. Стенды используют HTTP-реестр и пересылающие прокси на loopback; HTTPS, сертификаты, аутентификацию на прокси и коммерческие сервисы они не проверяют.

Если `npm install undici` проходит, а ваш код на Node.js 26 потом падает с `invalid onError method`, дело в несовпадении версий undici, а не в настройках npm: см. [fetch failed: invalid onError method в Node.js 26](/ru/guides/node-26-invalid-onerror-method).

## Не путайте шлюз с реестром

`registry` указывает сервис, который отдаёт метаданные пакетов. `proxy` и `https-proxy` задают сетевой шлюз, через который npm до этого сервиса добирается. «npm proxy repository» в Nexus — это менеджер репозиториев с кешем, доступный клиентам как реестр npm; это другой слой, не прямой (forward) HTTP-прокси. Задавайте URL реестра вашей организации и шлюз как отдельные параметры. [Настройка npm в Sonatype](https://help.sonatype.com/en/configuring-npm.html), [конфигурация npm](https://docs.npmjs.com/cli/v11/using-npm/config/).

Начните в проекте, где возникает ошибка:

```sh
node --version
npm --version
npm config get registry
npm config get proxy https-proxy noproxy
npm config get userconfig globalconfig
```

Смотрите этот вывод только у себя: в URL прокси могут быть учётные данные. URL реестра ничего не говорит о сетевом маршруте. Значения `null` у прокси — тоже: на стенде с одной лишь обычной переменной `HTTP_PROXY` npm всё равно шёл через прокси, хотя для обоих ключей показывал `null`.

## Проверьте npm через прокси: реестр, метаданные и архив

Посмотрев конфигурацию проблемного проекта, задайте явно четыре значения: `NPM_PROXY_URL` и `NPM_REGISTRY_URL` — утверждённые шлюз и реестр, `NPM_PACKAGE` — пакет без scope, закреплённый как `NAME@VERSION`, и `NPM_USERCONFIG` — абсолютный путь к утверждённому npmrc. Путь userconfig из вывода выше — отправная точка; убедитесь, что в выбранном файле есть всё нужное для аутентификации в реестре. Копировать токены в диагностический каталог не нужно.

Для приватного или scoped-пакета в утверждённой конфигурации должны остаться нужный реестр и привязанная к нему аутентификация. Запись `@scope:registry` — отдельная настройка: не рассчитывайте, что основной `--registry` её перекроет. Проверьте URL архива в метаданных и реестр, к которому npm обратился на самом деле. В базовых командах ниже взят пакет без scope, чтобы проверить только шлюз. [scope и аутентификация в npmrc](https://docs.npmjs.com/cli/v11/configuring-npm/npmrc/).

Для HTTPS-реестра можно использовать HTTP-шлюз: схема в URL шлюза определяет протокол соединения с самим шлюзом. Не вписывайте настоящие секреты литералами в команды, которые попадут в историю оболочки, и не оставляйте их в общих логах. Подстановка из переменной окружения не прячет раскрытый аргумент: его можно увидеть в локальном списке процессов.

Запустите все три проверки в одном новом каталоге вне существующих проектов. Реестр, утверждённый конфиг и прокси оставьте одними и теми же, а кеш для каждой проверки указывайте новый:

```sh
npm_proxy_check_dir="$(mktemp -d)"
cd "$npm_proxy_check_dir" || exit 1

npm ping --proxy="$NPM_PROXY_URL" --https-proxy="$NPM_PROXY_URL" \
  --registry="$NPM_REGISTRY_URL" --userconfig="$NPM_USERCONFIG" \
  --cache="$npm_proxy_check_dir/cache-ping" \
  --fetch-retries=0 --fetch-timeout=10000

npm view "$NPM_PACKAGE" version dist.tarball --json \
  --proxy="$NPM_PROXY_URL" --https-proxy="$NPM_PROXY_URL" \
  --registry="$NPM_REGISTRY_URL" --userconfig="$NPM_USERCONFIG" \
  --cache="$npm_proxy_check_dir/cache-view" \
  --fetch-retries=0 --fetch-timeout=10000
```

`ping` опрашивает реестр; `view` читает метаданные, включая URL архива. Ни одна из этих команд не скачивает и не проверяет архив пакета. [npm ping](https://docs.npmjs.com/cli/v11/commands/npm-ping/), [npm view](https://docs.npmjs.com/cli/v11/commands/npm-view/).

Для третьей проверки оставайтесь в том же диагностическом каталоге и используйте те же входные значения:

```sh
npm install "$NPM_PACKAGE" --ignore-scripts --no-audit --no-fund \
  --no-package-lock --save=false \
  --proxy="$NPM_PROXY_URL" --https-proxy="$NPM_PROXY_URL" \
  --registry="$NPM_REGISTRY_URL" --userconfig="$NPM_USERCONFIG" \
  --cache="$npm_proxy_check_dir/cache-install" \
  --fetch-retries=0 --fetch-timeout=10000
```

Проверьте, что у установленного пакета ожидаемые имя, версия и содержимое. Наш стенд сверяет точные файлы пакета, а не довольствуется ответом HTTP 200 или успешными метаданными. Новый кеш установки не даёт архиву, закешированному раньше, незаметно пройти эту проверку. Если доступны логи запросов шлюза, сверьтесь и с ними: корректный пакет сам по себе не доказывает, каким маршрутом он пришёл. Сохраните диагностический вывод для разбора, а временный каталог по окончании удалите.

В этой установке install-скрипты пакетов отключены. Она проверяет получение пакета из реестра, а не все зависимости и не полную установку проекта. `fetch-timeout` и отключённые повторы ограничивают отдельные запросы, но не задают десятисекундный лимит на всю установку. [npm install](https://docs.npmjs.com/cli/v11/commands/npm-install/), [параметры загрузки в npm](https://docs.npmjs.com/cli/v11/using-npm/config/).

## Конфликты настроек: что проверить до npm config set proxy

Для **одного и того же ключа** документированный приоритет в npm такой: параметры командной строки, затем переменные окружения `npm_config_*`, затем конфиг проекта, пользовательский и глобальный. `.npmrc` проекта может и дальше перекрывать новую пользовательскую настройку. В режиме глобальной установки конфиг проекта не читается. [Иерархия конфигурации npm в зафиксированной версии](https://github.com/npm/cli/blob/v11.19.1/workspaces/config/README.md), [файлы npmrc](https://docs.npmjs.com/cli/v11/configuring-npm/npmrc/).

Конфликты между разными ключами эта иерархия не решает. В нашем тесте на npm 11.19.1 пользовательский `https-proxy=A` оставался в силе, несмотря на `--proxy=B` в команде. Когда npm собрал итоговую конфигурацию, в ней остались оба значения, а код запросов к реестру выбрал `httpsProxy || proxy` — даже для нашего HTTP-реестра. Если нужен один шлюз, проверьте оба ключа и задайте им одно значение. [Код запросов к реестру в зафиксированной версии](https://raw.githubusercontent.com/npm/cli/v11.19.1/node_modules/npm-registry-fetch/lib/index.js).

Когда временная проверка сработала, сохраните в нужный файл значения без учётных данных; в примере они условные:

```sh
npm config set proxy=http://proxy.example:8080 \
  https-proxy=http://proxy.example:8080 --location=user
```

Если нужен уровень проекта, запустите команду с `--location=project` в каталоге этого проекта. Не храните учётные данные в `.npmrc`, который попадает в коммиты. npmrc поддерживает подстановку переменных окружения в значения, но при просмотре конфигурации может показываться уже раскрытое значение. У токенов реестра к тому же своя привязка к реестру, и учётными данными прокси они не являются. [Аутентификация и подстановки в npmrc](https://docs.npmjs.com/cli/v11/configuring-npm/npmrc/).

## Что показал наш стенд маршрутизации

[Стенд маршрутизации](https://ipvolt.com/downloads/npm-proxy-settings/npm-proxy-lab.mjs) поднимает фиктивный реестр и прокси A и B, отдаёт настоящий сгенерированный архив пакета и записывает каждый реальный запрос. В [результатах](https://ipvolt.com/downloads/npm-proxy-settings/results.json) есть точные аргументы команд, конфигурация и итог проверки содержимого.

| Заданный конфликт | Маршрут / результат | Что это даёт для диагностики |
| --- | --- | --- |
| Нет ни настроек прокси, ни переменных прокси в окружении | Напрямую; содержимое проверено | Базовый случай |
| Пользовательский npmrc задаёт A для обоих ключей | A; содержимое проверено | На этом стенде пользовательский конфиг работает |
| Проект B поверх пользовательского A, оба ключа | B; содержимое проверено | Проверьте файл проекта |
| `npm_config_proxy` и `npm_config_https_proxy` со значением A поверх проекта B | A; содержимое проверено | Проверьте переменные конфигурации в окружении процесса |
| Команда задаёт B для обоих ключей поверх окружения с A | B; содержимое проверено | Сравнивайте одинаковые ключи на одном уровне |
| Только обычная `HTTP_PROXY=A`, показаны значения null | A; содержимое проверено | Вывод npm config не полностью отражает маршрут |
| Обычная `NO_PROXY=127.0.0.1` плюс пользовательский прокси A, noproxy показан пустым | Напрямую; содержимое проверено | Обычная переменная обхода может продолжать действовать |
| B пропускает ping и метаданные, но отклоняет архив | ping и view проходят; install падает с E502, пакета нет | Проверяйте запрос архива отдельно |
| Пользовательский `https-proxy=A`, в проекте и в команде `proxy=B` | A; содержимое проверено | Приоритет команды для одного ключа не отменяет другой |

В восьми установках содержимое пакета совпало с ожидаемым. Девятая была намеренным сбоем, и пакет не установился; все девять случаев соответствовали своим критериям приёмки. Запасной путь через обычные переменные окружения реализован в HTTP-агенте npm той версии, что мы тестировали. Наблюдение про обход касается только точного совпадения с IPv4-адресом loopback; на подстановочные знаки, CIDR и другие клиенты оно не распространяется. [Агент npm в зафиксированной версии](https://raw.githubusercontent.com/npm/agent/v4.0.2/lib/proxy.js).

## Как убрать прокси в npm: удаляйте из нужного файла

Проверьте `.npmrc` проекта, а также пути к пользовательскому и глобальному конфигу, которые npm вывел выше. Если нужно удалить пользовательские настройки из примера:

```sh
npm config delete proxy https-proxy --location=user
```

Запись в проекте при этом всё ещё может взять верх. Настройки проекта удаляйте, только если действительно этого хотите, и запускайте команду из каталога проекта:

```sh
npm config delete proxy https-proxy --location=project
```

Наши четыре отдельные проверки редактирования конфигурации показывают: удаление пользовательских ключей не затронуло значения проекта, а последующее удаление ключей проекта убрало действующую пару в этой изолированной конфигурации. В документации npm сказано, что удаление убирает ключи из всех файлов, но код зафиксированной версии npm 11.19.1 удаляет их только из выбранного расположения — так вышло и в нашем эксперименте. Указывайте уровень явно и проверяйте результат. [Реализация удаления в зафиксированной версии](https://raw.githubusercontent.com/npm/cli/v11.19.1/lib/commands/config.js), [документация npm config](https://docs.npmjs.com/cli/v11/commands/npm-config/).

Проверьте также `npm_config_proxy`, `npm_config_https_proxy`, `HTTP_PROXY`, `HTTPS_PROXY` и переменные обхода в окружении того процесса, который на самом деле запускается. Удаление записей из файлов не удаляет значения из окружения. [Руководство по переменным окружения](/ru/guides/proxy-environment-variables) объясняет, как разные клиенты по-разному обрабатывают унаследованные настройки.

## Разберите оставшиеся ошибки

| На каком этапе сбой | Что проверить дальше |
| --- | --- |
| Нет соединения со шлюзом | Хост и порт, выбранный конфиг и настройки обхода в процессе |
| Реестр доступен, архив не скачивается | Хост и путь в `dist.tarball`, политика шлюза и запрос архива; учитывайте кеш |
| 407 от прокси | Аутентификация на шлюзе; см. [руководство по 407](/ru/guides/fix-proxy-error-407) |
| Ошибка аутентификации в реестре | Токен, реестр и scope; не смешивайте это с учётными данными шлюза |
| Ошибка проверки сертификата | Доверие к утверждённому CA и имя хоста для того соединения, которое на самом деле падает |
| Не скачивается Git-зависимость или падает загрузка в install-скрипте | Для загрузок Git по HTTP(S) см. [настройку прокси в Git](/ru/guides/git-proxy-setup); клиент каждого install-скрипта проверяйте отдельно. Настройки реестра npm эти маршруты не задают |

Чтобы npm доверял корпоративному CA, в документации описаны `cafile` и `strict-ssl`. Утверждённый набор CA получите у администратора и оставьте `strict-ssl` включённым. HTTP-стенды не проверяют ни одно исправление для HTTPS или корпоративного CA. [Настройка сертификатов в npm](https://docs.npmjs.com/cli/v11/using-npm/config/).

## Как повторить оба эксперимента

Скачайте оба скрипта и [README](https://ipvolt.com/downloads/npm-proxy-settings/README.md) в один каталог и запустите (нужны установленные Node и npm):

```sh
node npm-proxy-lab.mjs ./local-results.json
node npm-config-edit-check.mjs ./local-config-results.json
```

[Скрипт проверки конфигурации](https://ipvolt.com/downloads/npm-proxy-settings/npm-config-edit-check.mjs) и [его результаты](https://ipvolt.com/downloads/npm-proxy-settings/config-edit-results.json) дополняют данные о маршрутизации. Скрипты используют явно заданные временные пути к пользовательскому и глобальному конфигу и временные кеши, не трогают вашу пользовательскую конфигурацию и не выходят в сеть за пределы loopback. Прогон шёл на npm 11.19.1 / Node 26.10.0; актуальная документация v11 показывает более новую версию, поэтому запустите стенд заново, прежде чем переносить выводы на другой выпуск. Дополнительные npm-пакеты для запуска этих стендов не нужны. HTTPS/CONNECT, учётные данные прокси, аутентификация в приватном реестре, Git-зависимости, существующие lock-файлы и загрузки в lifecycle-скриптах в эксперимент не входят.

ipvolt продаёт мобильные прокси и резидентные прокси от $0.60/ГБ: [посмотрите цены](https://ipvolt.com/ru/pricing).

## Источники и дополнительное чтение

- [npm config](https://docs.npmjs.com/cli/v11/using-npm/config/)
- [npmrc](https://docs.npmjs.com/cli/v11/configuring-npm/npmrc/)
- [Pinned npm registry fetch](https://raw.githubusercontent.com/npm/cli/v11.19.1/node_modules/npm-registry-fetch/lib/index.js)

## Связанные руководства

- [Переменные окружения прокси: HTTP_PROXY и NO_PROXY](https://ipvolt.com/ru/guides/proxy-environment-variables.md)
- [Как исправить ошибку прокси 407, не гадая](https://ipvolt.com/ru/guides/fix-proxy-error-407.md)
- [Прокси для fetch в Node.js](https://ipvolt.com/ru/guides/nodejs-fetch-proxy.md)

## Об ipvolt

Примеры используют обобщённые настройки прокси со ссылками на оригинальную техническую документацию. Поведение конкретного продукта уточняйте у своего провайдера. ipvolt продаёт мобильные прокси и резидентные прокси от $0.60/ГБ.

[Читать оригинал на английском](https://ipvolt.com/guides/npm-proxy-settings.md)

## Подключите свой первый прокси.

Мобильные — от $9 в день. Резидентные — от $0.60 за ГБ.

[Купить мобильный прокси](https://ipvolt.com/dashboard/mobile)

[Купить резидентные прокси](https://ipvolt.com/dashboard/residential)

