개발 환경·Windows · · 약 16분 소요

Windows에서 npm·pnpm이 Clash를 타게: HTTP_PROXY·HTTPS_PROXY·NO_PROXY와 레지스트리 분기 규칙 실측 (2026)

Windows 로컬에서 npm이나 pnpm으로 의존성을 받을 때, 공식 registry.npmjs.org·registry.yarnpkg.com 축이 느리거나 끊기면 개발 리듬이 바로 깨집니다. 반대로 팀이 쓰는 국내 미러까지 전부 프록시로 돌리면 TLS·지연·인증서 검증에서 꼬이기도 합니다. 이 글은 이미 떠 있는 Clash(또는 mihomo) mixed-portHTTP_PROXY·HTTPS_PROXY로 붙이고, NO_PROXY분기 규칙으로 「해외 원본만 프록시, 국내 레지스트리는 직접」을 맞추는 실무 순서를 정리합니다. Docker가 호스트 Clash를 타는 글과 달리, 여기서는 호스트 셸의 Node 패키지 매니저가 중심입니다.

1. 왜 환경 변수와 Clash 규칙을 같이 봐야 하나

Node 생태계의 HTTP 클라이언트는 대부분 표준 프록시 환경 변수를 따릅니다. 그래서 터미널 세션에만 HTTP_PROXY를 넣어도 npm install이 곧바로 Clash로 나가는 경우가 많습니다. 하지만 Clash 쪽에서 이미 GEOIP,cn,DIRECT 같은 광역 규칙이 있어도, CONNECT 대상 호스트가 무엇인지에 따라 실제 아웃바운드가 달라집니다. 미러 도메인을 프록시로내면 불필요한 홉이 생기고, 반대로 npmjs만 직행으로 두면 해외 회선에서 타임아웃이 납니다. 사용자 검색 의도는 보통 「전부 한 번에 맞춰 달라」가 아니라 해외는 안정적으로, 국내 레지스트리는 빠르게입니다. 그래서 NO_PROXY로 애플리케이션 레벨에서 빼고, Clash rules로 네트워크 레벨에서 한 번 더 정리하는 이중선이 실무에서 가장 덜 깨집니다.

Cursor·IDE API 글처럼 도메인 단위로 묶는 습관을 그대로 가져오면, 같은 프로필 안에서 브라우저·터미널·패키지 매니저가 서로 다른 출구를 타도 디버깅이 수월합니다. Windows 11에서 GUI로 시스템 프록시를 켠 경우와, 오직 셸 변수로만 켠 경우의 차이도 아래에서 짚습니다.

2. Clash 쪽 전제: mixed-port·시스템 프록시와의 관계

Clash·Verge Rev 등 클라이언트에서 mixed-port(예: 7890)가 열려 있어야 http://127.0.0.1:7890 형태의 HTTP 프록시 연결이 성립합니다. 시스템 프록시를 켜 두면 많은 앱이 자동으로 따라가지만, npm·pnpm은 실행 환경에 따라 환경 변수를 더 확실히 믿는 편입니다. 팀 표준으로 「셸 프로필에만 넣는다」로 통일해 두면 CI 문서와도 맞물립니다. TUN 모드를 쓰는 경우에는 이론상 전역으로 나가지만, UWP 루프백·관리자 권한·DNS 변수가 겹치면 증상이 갈립니다. Windows 전반 설정은 Verge Rev·Windows 11 시스템 프록시·TUN 글과 짝을 이뤄 보시면 좋습니다.

한 줄 정리

로컬 개발 셸에서는 127.0.0.1:mixed-port를 가리키는 HTTP(S)_PROXY가 기본축이고, Clash 규칙은 그 다음 단계에서 트래픽을 노드·DIRECT로 나눕니다.

3. PowerShell·CMD에서 HTTP_PROXY·HTTPS_PROXY 넣기

현재 세션에만 적용하려면 PowerShell에서 $env:HTTP_PROXY="http://127.0.0.1:7890"처럼 설정합니다. HTTPS_PROXY도 동일한 HTTP 프록시 URL을 넣는 관행이 흔합니다(Clash mixed-port가 CONNECT를 처리). 사용자 계정에 고정하려면 시스템 환경 변수 UI나 setx를 쓰지만, 새 터미널을 열어야 반영되고 잘못 넣으면 다른 앱까지 영향을 받으니 개발 전용 프로필 스크립트로 감싸는 편이 안전합니다.

# PowerShell: current session only (adjust port)
$env:HTTP_PROXY  = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
npm ping

Git Bash·MSYS를 쓰면 POSIX 스타일 export HTTP_PROXY=...가 통합니다. WSL2 안의 Linux 셸은 Windows localhost와 주소 체계가 달라서, 그 경우에는 WSL2·미러 네트워크·호스트 IP 글의 절차를 먼저 맞춰야 합니다. 본 글은 호스트 Windows 네이티브 셸을 전제로 합니다.

4. NO_PROXY로 국내 미러·사내망·localhost 제외

팀에서 registry.npmmirror.com·사내 Verdaccio·Artifactory 호스트를 쓰면, 이들을 프록시 경유로 보낼 이유가 거의 없습니다. NO_PROXY에 호스트명·접미 패턴·루프백을 넣습니다. 예시는 팀 정책에 맞게 줄이거나 늘리면 됩니다.

$env:NO_PROXY = "localhost,127.0.0.1,::1,.npmmirror.com,.tencent.com,registry.internal.corp"

쉼표 구분과 앞에 점을 붙인 접미 일치(.example.com)는 운영자들이 익숙한 관례입니다. NO_PROXY가 비어 있으면 미러까지 Clash를 타서 지연만 늘거나, 회사 방화벽과 이중으로 걸려 실패하는 경우가 있습니다. 반대로 npmjs 관련 호스트를 여기서 빼면 안 되므로, 미러 전용 도메인만 나열하는 습관이 좋습니다.

5. npm·pnpm 전용 설정과 env의 우선순위

npm config set proxy·https-proxy는 사용자·프로젝트 .npmrc에 남습니다. 팀원마다 Clash 포트가 다르면 env 쪽이 유지보수에 유리합니다. pnpm은 npm과 동일하게 HTTP_PROXY를 존중하는 편이며, 모노레포에서는 루트 .npmrcregistry=만으로 출구가 갈리기도 합니다. 공식 레지스트리를 쓰는데도 느리면 registry를 바꾸기 전에, 먼저 프록시·분기가 제대로 타는지 확인하는 순서가 혼용 오류를 줄입니다.

# Optional: npm-level mirror (example; use your org mirror)
npm config set registry https://registry.npmmirror.com

레지스트리 URL을 미러로 바꾼 뒤에도 tarball이 여전히 registry.npmjs.org를 가리키는 메타데이터가 있을 수 있습니다. 그때는 Clash 쪽에서 npmjs 축을 프록시 그룹으로 보내는 것이 안전합니다. 구독·노드가 안정적인지는 별도로 Windows 구독·TLS·DNS 로그 글에서 점검할 수 있습니다.

6. Clash 분기 규칙 예시: npmjs는 프록시, 미러는 DIRECT

규칙은 프로필 상단에 둘수록 우선합니다. 아래는 개념 스니펫이며, 정책 그룹 이름은 본인 YAML에 맞게 바꿉니다. 핵심은 레지스트리 호스트를 이름으로 고정하고, 나머지 트래픽은 기존 GEOIP·MATCH 흐름에 맡기는 것입니다.

# Example rules — adjust policy group names to your config
rules:
  - DOMAIN-SUFFIX,npmjs.org,PROXY
  - DOMAIN-SUFFIX,yarnpkg.com,PROXY
  - DOMAIN-SUFFIX,nodejs.org,PROXY
  - DOMAIN-SUFFIX,npmmirror.com,DIRECT
  - DOMAIN-SUFFIX,tencent.com,DIRECT

rule-providers나 GEOIP와 섞을 때는 충돌 순서를 한 번 출력해 보는 것이 좋습니다. 고급 패턴은 라우팅 가이드와 함께 읽으면, 왜 특정 tarball 요청만 다른 노드로 나갔는지 로그로 역추적하기 쉽습니다.

7. 자주 나는 오류: 타임아웃·혼용·strict-ssl

ETIMEDOUT·ECONNRESET은 대개 프록시 미적용, 잘못된 포트, Clash가 꺼짐, 노드 불능 중 하나입니다. curl -I https://registry.npmjs.org로 셸 프록시를 먼저 검증하고, 같은 창에서 npm ping을 실행해 보세요. 회사 SSL 검사 장비를 타면 UNABLE_TO_VERIFY_LEAF_SIGNATURE류가 나올 수 있는데, 이때는 strict-ssl을 함부로 끄지 말고 신뢰 체인·사내 루트 인증서 쪽을 봐야 합니다. 프록시와 직접 연결이 섞여 패키지 버전이 꼬이면 lockfile을 재생성하기 전에, 같은 registry·같은 프록시 상태에서 한 번에 설치하는지 확인합니다.

보안: 공용 PC에 setx HTTPS_PROXY ...로 영구 저장하면 다른 사용자 세션에도 노출될 수 있습니다. 가능하면 사용자 스코프·도구별 스크립트로 한정하세요.

8. 실측 점검 순서

첫째, Clash 대시보드나 로그에서 mixed-port 리슨과 테스트 노드 지연을 확인합니다. 둘째, 프록시를 켠 셸에서 외부 HTTPS 한 번·미러 호스트 한 번을 curl로 비교합니다. 셋째, npm config get registry와 pnpm의 동일 설정을 확인합니다. 넷째, Clash 규칙 히트 로그로 npmjs.org 요청이 기대한 정책 그룹으로 나갔는지 봅니다. 다섯째, 문제가 남으면 DNS 모드(fake-ip 여부)를 DNS 누수 실측 글과 교차해 보세요.

프록시가 비어 있지 않은지

gci env:*proxy*(PowerShell)로 대소문자 변종까지 확인합니다. IDE 내장 터미널은 부모 프로세스 환경을 물려받지 못하는 경우가 있습니다.

pnpm store와 캐시

프록시 설정을 바꾼 뒤에도 오류가 지속되면 pnpm store prune 전에, 동일 네트워크 조건에서 재현되는지부터 좁히세요.

정리하면, Windows 로컬 셸에서 npm·pnpmClash로 안정화하는 핵심은 HTTP_PROXY·HTTPS_PROXY로 mixed-port에 붙이고, NO_PROXY로 국내 registry·사내 호스트를 직접 연결로 빼며, Clash 분기 규칙으로 npmjs.org 등 해외 축만 원하는 노드로 보내는 삼단 구조입니다. 상용 VPN 앱에 비해 Clash 계열은 규칙 파일과 로그로 원인을 좁히기 쉬워, 패키지 다운로드처럼 반복적인 출국 트래픽을 다루기에 잘 맞습니다.

Clash를 무료로 내려받아 mixed-port와 프로필을 정리한 뒤, 위 순서대로 셸 변수와 규칙을 맞춰 보시면 타임아웃과 레지스트리 혼용 문제를 한 단계 줄일 수 있습니다.

주제 관련도가 높은 읽을거리 — 같은 카테고리의 Clash 실전 가이드.