Skip to content

Instantly share code, notes, and snippets.

@casamia918
Last active February 25, 2024 08:18
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save casamia918/aa8c986504d942223379e0af0c15644f to your computer and use it in GitHub Desktop.
Save casamia918/aa8c986504d942223379e0af0c15644f to your computer and use it in GitHub Desktop.
npx와 bin 파고들기

references




1. 호기심 발생

개인 프로젝트를 하면서 ReactNative 앱을 하나 만들려고 찾다가, 가장 잘 만들어진 boilerplate인 ignite를 알게 되었다.

그래서 이 ignite 프로젝트를 써서 학습중인데, 문득 ignite가 어떻게 설치되는지 설치 과정이 좀 궁금해졌다.

ignite git repo 를 보면 내가 설치한 ignite 프로젝트 코드랑은 다른데, npx ignite-cli new PizzaApp 이 커맨드가 어떻게 작동하는지 호기심이 생겼다.

예전부터 cra에서 새로운 프로젝트를 만들려고 할 때, npx create-react-app my-app 이 명령어가 어떻게 실행되는지 궁금했는데 마침 이번 기회에 좀 파고들어야 겠다는 생각을 하게 되었다.




2. Deep Dive

2.1 Start - npx 이해

먼저 npx가 뭔지 한마디로 설명하자면, npm package에서 정의한 binary를 실행하는 러너이다.

npm의 binary script들은 node_modules/.bin 이라는 폴더에 들어가게 되고, npm run {command} 를 통해서 이 binary 를 실행할 수 있었다. (npm run은 .bin 폴더에 있는 스크립트들 뿐만 아니라 package.json에서 scripts에서 정의한걸 실행할 수 있기도 하다.)

이 npm run을 좀더 쓰기 쉽게 만든게 npx라고 보면 된다.

ignite 설치하는 방법을 보면, npx ignite-cli new PizzaApp 이라고 나와있는데

문제는 나는 현재 글로벌로 ignite-cli를 설치한 적이 없는데 어떻게 npx ignite-cli가 동작하는지 궁금했다.

좀 찾아보니, npx가 어떻게 동작하는지 설명하는 문서가 있었는데, npx는

  • 로컬 노드 모듈에 있는 node_modules/.bin 폴더 에 있는 스크립트를 실행할수 있기도 하고
  • gloabel .bin에 있는 스크립트를 실행할 수 있기도 하고
  • remote에서 download하여 one-off(일회용)로 package를 설치한 다음 bin을 실행할 수

있었다.

npx doc

210715-npxdoc

오케이 그럼 npx ignite-cli 이 명령어는, "npm repository에 있는 ignite-cli 를 one-off 로 설치한다음에, 그 안에서 bin을 실행해라" 이렇게 이해할 수 있었다.




2.2 처음 help 메시지는 어디서?

그렇게 npx ignite-cli를 실행해보면 아래와 같은 메시지가 떴다

210715-npx_ignite-cli

그럼 이 메시지는 어떻게 뜬걸까?

일단 ignite-cli 레포지토리에서 위의 메시지가 출력을 정의한 부분은, src/cli.ts 였다.

210715-src꞉cli_ts

그럼 어디선가 이 src/cli.ts에 있는 저 run 함수를 실행한건데,

레포지토리를 뒤지다보니, bin/ignite 에서 답을 찾을 수 있다.

210715-bin꞉ignite

라인 28을 보면 sourceDir + "/cli" 모듈을 불러온다음에, run을 실행하는 것이었다. (sourceDir 변수가 확정되는 부분은 이따 보기로 하자)

그리고 저 bin/ignite 스크립트는, package.json에서 정의되어 있었다.

210715-package_json

package.json을 찾아보니 bin 필드 설명이 이렇게 나와이었다

210715-npmdoc_packagejson-bin

아하. 그럼 이제 전체 실마리가 잡히는 것 같다

    1. npx ignite-cli를 입력하면 먼저 ignite-cli 패키지가 one-off로 설치된다
    1. 그리고 설치할 때, npm에서는 package.json에서 bin 필드에 지정되어 있는 파일의 symlink를 .bin 폴더에 생성한다.
    1. 이 symlink 덕분에 npx는 실행해야 할 스크립트 파일을 알 수 있고, 그래서 bin/ignite를 실행하게 된다.




2.3. sourceDir에서 build는 대체 어디에?

이제 저 npx 커맨드가 거의 다 이해가 됐는데, 아직까지 이해가 가지 않는 부분이 하나 있엇다.

분명 bin/ignite를 보면 sourceDir = __dirname + "/../build" 이렇게 지정을 하고 있고, 그 다음에 devMode condition을 따로 주고 있는데

아무리봐도 우리가 이 ignite-cli를 쓸때는 devMode를 쓰는것 같진 않고, build가 완료된걸 쓰는 것 같은데

도저히 저 build 폴더가 어디서 생성되는지 찾을 수 없었다.



먼저 일단 좀 단서를 찾아보면

  • package.json에서는 build script를 정의하고 있었고, build는 곧 typescript compile을 의미한다.

210715-package_json_scripts

  • typescript compile을 할 경우 outDir이 build 폴더이다

210715-tsconfig



흠.... 역시나 build 스크립트가 실행되면서 build 폴더가 생성되는게 맞는데

그럼 build 스크립트는 언제 실행되나???

라고 고민을 하다가, package.json에 있는 scripts에서 ci:publish에서 yarn build를 호출하고 있음을 알게 되었다.



앗 ci가 붙은거 보면 혹시 저거 ci/cd 할때 그걸 말하는건가? 싶어서

.circleci/config.yml 을 들어가봤는데, 빙고! 여기서 publish할 때 yarn ci:publish 를 실행하라고 정의된걸 확인할 수 있었다.

210715-circleci-1 210715-circleci-2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment