npm install 말고 npx
create-react-app을 npx로 실행하면서도 npm과 뭐가 다른지 설명 못 하겠다면요.
npx create-react-app my-app 한 번쯤은 쳐봤을 거예요. 근데 "npm이랑 npx가 뭐가 다른데?"라고 물으면 선뜻 대답하기 애매하죠. 저도 한동안 그냥 "npx 쓰면 설치 안 해도 된다" 정도로만 알고 넘어갔거든요.
npm은 패키지를 관리하는 도구
npm은 Node.js의 패키지 매니저예요. npm install로 패키지를 설치하고, package.json으로 의존성을 추적하고, npm run으로 스크립트를 실행하죠.
여기서 핵심은 npm이 "설치"와 "관리" 에 초점을 맞춘 도구라는 점이에요. 패키지를 다운로드해서 node_modules에 넣고, 버전을 관리하고, 의존성 트리를 해결하는 게 npm의 일이에요.
그럼 패키지를 설치하지 않고 그냥 한 번 실행만 하고 싶을 때는 어떻게 할까요?
npx가 등장한 이유
npm 5.2.0(2017년)부터 npx가 함께 번들되기 시작했어요. npx의 역할은 단순해요. 패키지를 실행 하는 거예요.
npx로 패키지를 실행하면 이런 일이 벌어져요.
첫 번째
로컬 node_modules/.bin에 해당 패키지가 있는지 확인
두 번째
없으면 npm 캐시에 임시로 설치
세 번째
실행이 끝나면 PATH에서 제거
그래서 npx create-react-app my-app을 치면, create-react-app을 전역에 설치하지 않고도 최신 버전을 받아서 바로 실행할 수 있어요. 한 번 쓰고 마는 CLI 도구에 딱이죠.
사실 npx는 내부적으로 npm exec의 래퍼예요. 두 명령어는 거의 같은 동작을 하지만, npx가 타이핑이 짧고 편해서 일상적으로는 npx를 더 많이 쓰게 돼요.
npm run과 npx, 뭐가 다를까
로컬에 설치된 패키지의 바이너리를 실행하는 방법은 두 가지가 있어요.
첫 번째는 package.json의 scripts에 등록하고 npm run으로 실행하는 방법이에요.
{
"scripts": {
"lint": "eslint ."
}
}npm run lint두 번째는 npx로 직접 실행하는 방법이에요.
npx eslint .결과는 같아요. 둘 다 node_modules/.bin/eslint을 찾아서 실행하거든요. 다만 npm run은 package.json에 스크립트를 미리 등록해둬야 하고, npx는 그냥 바로 실행할 수 있다는 차이가 있어요.
프로젝트에서 반복적으로 쓰는 도구는 scripts에 등록해두는 게 팀원들과 공유하기 좋고, 일회성으로 쓰는 도구는 npx가 편해요.
npx에는 버전을 지정하는 기능도 있어요. npx typescript@4.9.5 --version처럼 특정 버전을 골라서 실행할 수 있죠. 프로젝트 설치 버전과 다른 버전으로 잠깐 테스트해볼 때 유용해요.
본인 소개 npx 패키지 만들기
npx의 동작 원리를 이해했으니 직접 만들어볼게요. npx 내이름을 치면 터미널에 본인 소개가 뜨는 패키지예요.
먼저 프로젝트를 하나 만들어요.
mkdir my-card && cd my-card
npm init -ypackage.json에 bin 필드를 추가해요. 이 필드가 npx한테 "이 파일을 실행해"라고 알려주는 역할을 해요.
{
"name": "my-card",
"version": "1.0.0",
"bin": "./bin/card.js"
}bin/card.js 파일을 만들어요. 첫 줄의 셔뱅(shebang)이 중요해요. 이게 없으면 운영체제가 이 파일을 Node.js로 실행해야 한다는 걸 모르거든요.
#!/usr/bin/env node
console.log(`
┌─────────────────────────────────┐
│ │
│ 홍길동 / Frontend Developer │
│ │
│ GitHub: github.com/gildong │
│ Blog: gildong.dev │
│ │
└─────────────────────────────────┘
`)npm에 배포하면 끝이에요.
npm login
npm publish --access publicscoped 패키지(@scope/name)는 기본이 비공개라서 --access public을 붙여야 해요. 배포 전에 npm pack --dry-run으로 어떤 파일이 포함되는지 확인해보는 것도 좋아요.
이제 누구든 터미널에서 이렇게 실행할 수 있어요.
npx my-cardchalk 같은 라이브러리를 추가하면 색상도 넣을 수 있고, boxen으로 예쁜 박스 레이아웃도 만들 수 있어요. 면접 때 "제 소개는 npx 제이름으로 확인하실 수 있어요"라고 하면 꽤 인상적이겠죠.
정리하면
npm은 패키지를 설치하고 관리 하는 도구, npx는 패키지를 실행 하는 도구예요. 이 한 가지 차이가 전부예요.
일회성 CLI 도구를 전역 설치 없이 쓰고 싶을 때, 프로젝트에 등록하지 않고 바로 실행하고 싶을 때, 특정 버전으로 잠깐 테스트하고 싶을 때 npx를 쓰면 돼요. npx로 codemod를 돌리는 것도 같은 맥락이에요. 궁금하다면 codemod가 뭔지 다룬 글도 한번 읽어보세요.