Node 버전을 여러 개 설치해두고 필요할 때 바꾸는 도구로 nvm을 기억하는 사람이 많습니다. README의 사용 예제도 `nvm install 24`, `nvm use 22`, `nvm use 20` 순서로 진행됩니다. 하지만 이 명령이 실제로 바꾸는 대상은 시스템 전체의 Node 설정이 아니라 현재 셸이 참조하는 실행 환경입니다. 같은 터미널에서 `node -v`의 결과가 달라지는 이유도 여기에 있습니다.
프로젝트 구조는 이 실행 모델을 숨기지 않습니다. nvm은 사용자별로 설치되고 셸별로 호출됩니다. install.sh는 저장소를 `~/.nvm`에 clone한 다음 `~/.bashrc`, `~/.bash_profile`, `~/.zshrc`, `~/.profile` 가운데 적절한 프로필에 `nvm.sh`를 source하는 구문을 추가합니다. nvm이 별도 데몬으로 계속 실행되는 방식이 아니라, 셸이 시작될 때 함수와 환경 변수를 읽어들이는 방식이라는 뜻입니다. `--no-use` 옵션으로 기본 Node를 자동 선택하는 시점을 늦출 수 있는 것도 같은 설계에서 나옵니다.
이 방식은 로컬 개발에서 꽤 자연스럽습니다. 디렉터리에 `.nvmrc`를 두면 프로젝트가 사용할 Node 버전을 선언할 수 있고, 셸의 실행 대상과 프로젝트 설정을 연결할 수 있습니다. 다만 셸이 바뀌면 전제도 바뀝니다. Docker에서 비대화형 bash를 실행하면 일반적인 프로필 파일이 source되지 않기 때문에 README는 `BASH_ENV`를 지정하는 구성을 안내합니다. CI/CD용 예제도 `source $NVM_DIR/nvm.sh && nvm install`로 환경을 먼저 복원한 뒤 명령을 실행하고, ENTRYPOINT에서 다시 nvm 환경을 읽습니다.
여기서 nvm의 장점과 비용이 동시에 드러납니다. 여러 Node 버전을 한 사용자 환경에 두고 필요한 순간 PATH를 바꿀 수 있어 프로젝트 전환은 빠릅니다. 반면 `node`가 어느 파일을 가리키는지는 셸 초기화와 source 순서, 컨테이너의 진입점에 달려 있습니다. 로컬 셸에서는 맞던 버전이 자동화 환경에서 사라지는 문제를 만났다면 설치 여부보다 환경 로드 여부를 먼저 봐야 합니다.
nvm을 도입할 때 확인할 항목도 단순합니다. 현재 프로필이 `nvm.sh`를 읽는지, 비대화형 bash에 `BASH_ENV`나 명시적 source가 있는지, `.nvmrc` 적용 뒤 실제 `node -v`가 기대한 값을 내는지 확인하면 됩니다. 플러그인을 더 붙이는 것보다 실행 직전에 어떤 셸이 어떤 PATH를 구성하는지 파악하는 편이 재현성에 직접적인 도움이 됩니다.