개발 환경 설정
Node.js와 패키지 관리자를 준비하고 Nest CLI로 프로젝트를 생성해 개발 서버의 실행 결과까지 확인합니다.
NestJS의 특징과 구조를 살펴봤으니, 이제 개발 환경을 직접 준비합니다. 환경 준비는 명령어를 외우는 일이 아니라, 런타임, 패키지 관리자, CLI, 프로젝트, HTTP 응답이라는 단계를 차례로 통과하는 과정입니다. 각 단계의 결과가 다음 단계의 입력이 되므로, 막혔을 때는 어느 단계까지 통과했는지부터 확인합니다.
NestJS 개발 환경 준비와 실패 경계
runtime·package manager·CLI·scaffold·첫 HTTP 응답에서 산출물과 통과 증거가 단계마다 바뀐다.
Nest 환경 · 단계별 통과 신호
런타임부터 첫 HTTP 응답까지, 막힌 경계를 순서대로 확인합니다
프로젝트 생성용 CLI 실행 방식은 하나를 선택합니다. 생성 후 start:dev는 프로젝트의 로컬 CLI를 사용하며, 로그 문구보다 설정된 포트의 실제 응답을 확인합니다.
Node.js와 패키지 관리자를 확인한 뒤 전역 nest 또는 npx 생성 CLI 하나를 선택한다. scaffold가 만든 프로젝트와 의존성은 start:dev의 입력이며, 생성 후에는 프로젝트 로컬 CLI가 실제 HTTP 응답까지 실행한다.
관계도 해설과 예제 원자료
| 경계 | 확인 · 실행 | 통과 신호 | 막히면 먼저 볼 곳 |
|---|---|---|---|
| Node.js 런타임 | node --version |
Nest와 CLI의 최소 요구를 만족하는 현재 지원 중인 LTS를 사용한다. | Node.js release status, 설치 경로, 새로 연 shell의 PATH |
| 패키지 관리자 | npm --version |
선택한 도구가 실행되고 프로젝트에서는 한 종류의 lockfile을 유지한다. | Node.js·npm 설치, shell 재시작, 팀이 정한 npm·Yarn·pnpm 기준 |
| Nest CLI |
또는 |
new 등 CLI 명령 도움말을 확인한다. |
전역 설치 권한·버전·binary 경로 또는 npx의 네트워크 접근 |
| 프로젝트 scaffold |
또는 |
프로젝트 폴더, package.json, src/와 설치된 의존성이 생긴다. |
생성 위치의 쓰기 권한, 네트워크, 선택한 패키지 관리자 |
| 개발 서버와 첫 응답 | npm run start:dev |
애플리케이션이 설정된 포트에서 요청을 받고 기본 route가 응답한다. | package.json이 있는 현재 폴더, 터미널 예외, 포트 충돌, route 경로 |
- 1. Node.js 런타임
- 확인
node --version - 통과 Nest와 CLI 최소 요구를 만족하는 현재 지원 중인 LTS다.
- 진단 release status, 설치 경로, 새 shell의
PATH를 본다. - 2. 패키지 관리자
- 확인 교재 기준은
npm --version이다. - 통과 선택한 도구가 실행되고 lockfile을 한 종류로 유지한다.
- 진단 Node.js·npm 설치와 팀의 npm·Yarn·pnpm 기준을 확인한다.
- 3. Nest CLI
- 확인
nest --help또는npx @nestjs/cli@latest --help - 통과
new등 명령 도움말이 나온다. - 진단 전역 설치의 권한·버전·경로 또는
npx네트워크를 본다. - 4. 프로젝트 scaffold
- 실행
nest new my-nestjs-app또는npx @nestjs/cli@latest new my-nestjs-app - 통과 프로젝트 폴더,
package.json,src/와 의존성이 생긴다. - 진단 생성 위치 권한, 네트워크, 패키지 관리자 선택을 본다.
- 5. 개발 서버와 첫 응답
- 실행 프로젝트 폴더에서
npm run start:dev - 통과 설정된 포트의 기본 route가 응답한다.
- 진단 현재 폴더, 터미널 예외, 포트 충돌, route 경로를 본다.
start:dev script는 프로젝트에 설치된 Nest CLI를 사용한다. 정확한 로그 문구보다 어느 경계까지 통과했는지를 확인한다.이 예의 조건
- 두 박스는 같은 실행의 진행 정보와 자료·결과를 관찰하는 고정 역할입니다. 박스의 좌우·위아래 위치를 별도 호출 순서로 해석하지 않습니다.
- 조건별 종료는 대안입니다. 실패 뒤 정상 후속 단계를 실행하거나 독립 비교 사례를 같은 요청으로 연결하지 않습니다.
관계도의 보충 설명
| 순번 | 원문 표시 |
|---|---|
| 1 | NestJS 개발 환경 준비와 실패 경계 |
| 장면 | 관찰 값 | 전환 이유 |
|---|---|---|
| 도구 경계 확인 Node·패키지 관리자·선택 CLI의 실행을 확인합니다. | 증거: version·help · CLI: 한 방식 선택 | 프로젝트 생성 전 도구를 확인합니다. |
| scaffold 산출물 new가 프로젝트 폴더·package.json·src·의존성을 만듭니다. | 산출물: 프로젝트·의존성 · lockfile: 한 종류 | 개발 실행의 입력이 생깁니다. |
| 첫 HTTP 확인 start:dev의 로컬 CLI로 실행하고 설정 포트의 응답을 확인합니다. | 실행: 프로젝트 local CLI · 증거: 실제 HTTP 응답 | 로그 문구보다 마지막 실행 경계를 확인합니다. |
NestJS 개발 환경 준비와 실패 경계
runtime·package manager·CLI·scaffold·첫 HTTP 응답에서 산출물과 통과 증거가 단계마다 바뀐다.
Nest 환경 · 단계별 통과 신호
런타임부터 첫 HTTP 응답까지, 막힌 경계를 순서대로 확인합니다
프로젝트 생성용 CLI 실행 방식은 하나를 선택합니다. 생성 후 start:dev는 프로젝트의 로컬 CLI를 사용하며, 로그 문구보다 설정된 포트의 실제 응답을 확인합니다.
Node.js와 패키지 관리자를 확인한 뒤 전역 nest 또는 npx 생성 CLI 하나를 선택한다. scaffold가 만든 프로젝트와 의존성은 start:dev의 입력이며, 생성 후에는 프로젝트 로컬 CLI가 실제 HTTP 응답까지 실행한다.
관계도 해설과 예제 원자료
| 경계 | 확인 · 실행 | 통과 신호 | 막히면 먼저 볼 곳 |
|---|---|---|---|
| Node.js 런타임 | node --version |
Nest와 CLI의 최소 요구를 만족하는 현재 지원 중인 LTS를 사용한다. | Node.js release status, 설치 경로, 새로 연 shell의 PATH |
| 패키지 관리자 | npm --version |
선택한 도구가 실행되고 프로젝트에서는 한 종류의 lockfile을 유지한다. | Node.js·npm 설치, shell 재시작, 팀이 정한 npm·Yarn·pnpm 기준 |
| Nest CLI |
또는 |
new 등 CLI 명령 도움말을 확인한다. |
전역 설치 권한·버전·binary 경로 또는 npx의 네트워크 접근 |
| 프로젝트 scaffold |
또는 |
프로젝트 폴더, package.json, src/와 설치된 의존성이 생긴다. |
생성 위치의 쓰기 권한, 네트워크, 선택한 패키지 관리자 |
| 개발 서버와 첫 응답 | npm run start:dev |
애플리케이션이 설정된 포트에서 요청을 받고 기본 route가 응답한다. | package.json이 있는 현재 폴더, 터미널 예외, 포트 충돌, route 경로 |
- 1. Node.js 런타임
- 확인
node --version - 통과 Nest와 CLI 최소 요구를 만족하는 현재 지원 중인 LTS다.
- 진단 release status, 설치 경로, 새 shell의
PATH를 본다. - 2. 패키지 관리자
- 확인 교재 기준은
npm --version이다. - 통과 선택한 도구가 실행되고 lockfile을 한 종류로 유지한다.
- 진단 Node.js·npm 설치와 팀의 npm·Yarn·pnpm 기준을 확인한다.
- 3. Nest CLI
- 확인
nest --help또는npx @nestjs/cli@latest --help - 통과
new등 명령 도움말이 나온다. - 진단 전역 설치의 권한·버전·경로 또는
npx네트워크를 본다. - 4. 프로젝트 scaffold
- 실행
nest new my-nestjs-app또는npx @nestjs/cli@latest new my-nestjs-app - 통과 프로젝트 폴더,
package.json,src/와 의존성이 생긴다. - 진단 생성 위치 권한, 네트워크, 패키지 관리자 선택을 본다.
- 5. 개발 서버와 첫 응답
- 실행 프로젝트 폴더에서
npm run start:dev - 통과 설정된 포트의 기본 route가 응답한다.
- 진단 현재 폴더, 터미널 예외, 포트 충돌, route 경로를 본다.
start:dev script는 프로젝트에 설치된 Nest CLI를 사용한다. 정확한 로그 문구보다 어느 경계까지 통과했는지를 확인한다.이 예의 조건
- 두 박스는 같은 실행의 진행 정보와 자료·결과를 관찰하는 고정 역할입니다. 박스의 좌우·위아래 위치를 별도 호출 순서로 해석하지 않습니다.
- 조건별 종료는 대안입니다. 실패 뒤 정상 후속 단계를 실행하거나 독립 비교 사례를 같은 요청으로 연결하지 않습니다.
관계도의 보충 설명
| 순번 | 원문 표시 |
|---|---|
| 1 | NestJS 개발 환경 준비와 실패 경계 |
| 장면 | 관찰 값 | 전환 이유 |
|---|---|---|
| 도구 경계 확인 Node·패키지 관리자·선택 CLI의 실행을 확인합니다. | 증거: version·help · CLI: 한 방식 선택 | 프로젝트 생성 전 도구를 확인합니다. |
| scaffold 산출물 new가 프로젝트 폴더·package.json·src·의존성을 만듭니다. | 산출물: 프로젝트·의존성 · lockfile: 한 종류 | 개발 실행의 입력이 생깁니다. |
| 첫 HTTP 확인 start:dev의 로컬 CLI로 실행하고 설정 포트의 응답을 확인합니다. | 실행: 프로젝트 local CLI · 증거: 실제 HTTP 응답 | 로그 문구보다 마지막 실행 경계를 확인합니다. |
그림은 Node.js와 패키지 관리자를 확인한 뒤, 전역 nest와 npx 가운데 하나의 방식으로 CLI를 실행해 프로젝트를 만들고, 그 프로젝트의 start:dev로 실제 HTTP 응답까지 확인하는 흐름입니다. 프로젝트를 만든 뒤에는 생성 때 쓴 CLI가 아니라 프로젝트 안에 설치된 로컬 CLI가 개발 서버를 실행합니다. 아래 표는 단계마다 확인할 명령, 통과했다는 신호, 막혔을 때 먼저 볼 곳을 정리합니다.
Node.js와 패키지 관리자
NestJS 애플리케이션은 Node.js에서 실행됩니다. Node.js와 npm을 설치한 뒤, 먼저 터미널에서 두 명령이 동작하는지 확인합니다.
node --version
npm --versionNestJS 12는 애플리케이션을 실행할 때와 CLI로 코드를 생성할 때 요구하는 Node.js 버전이 다릅니다. 공식 시작 문서에 따르면 애플리케이션 실행에는 20.19 이상(22.x 계열은 22.12 이상)이, nest new와 nest generate 같은 생성 명령에는 22.22.3 이상, 24.15 이상, 26 이상 가운데 하나가 필요합니다. 또 이전 안내는 Jest가 ECMAScript 모듈(ESM)로만 배포되는 NestJS 12 패키지를 불러오려면 Node.js 24.9 이상이 필요하다고 밝힙니다.
이 교재는 세 조건을 모두 만족하는 Node.js 24 LTS(24.15 이상)를 기준으로 합니다. 2026년 10월 28일에 LTS가 된 Node.js 26도 같은 조건을 만족하므로, 새 환경이라면 Node.js 릴리스 표에서 현재 지원 중인 LTS를 확인해 고르면 됩니다. 설치는 Node.js 다운로드 페이지나 운영체제에 맞는 버전 관리자를 쓰며, npm 설치 문서도 Node.js와 npm을 함께 관리할 수 있는 버전 관리자를 권장합니다.
이 교재의 명령은 npm을 기준으로 합니다. nest new에서 Yarn, pnpm, Bun을 고를 수도 있지만, 한 프로젝트에서는 팀이 정한 패키지 관리자와 그 잠금 파일(lockfile)을 일관되게 씁니다. Yarn이나 pnpm을 고른다면 고정된 전역 설치 예제를 따르기보다 Yarn 설치 문서나 pnpm 설치 문서의 현재 안내를 확인합니다.
더 깊이: 실행 조건이 20.19와 22.12에서 갈리는 이유
NestJS 12의 핵심 패키지는 ECMAScript 모듈(ESM)로만 배포됩니다. 그래서 이 교재처럼 CommonJS로 만든 프로젝트가 @nestjs/core를 불러올 때는, Node.js가 require()로 ES 모듈을 읽는 기능인 require(esm)이 필요합니다. 이 기능은 Node.js 22.12와 20.19부터 실험 플래그 없이 켜졌고, 21.x 계열에는 들어가지 않았습니다. @nestjs/core의 package.json은 여전히 Node.js 20 이상만 적어 두었지만, 이전 안내가 실행 조건을 20.19 이상과 22.12 이상으로 따로 밝히고 21.x를 지원하지 않는다고 말하는 것은 이 때문입니다.
require(esm)에는 조건이 있습니다. 불러오는 모듈과 그 모듈이 import하는 모듈 전체에 최상위 await가 하나도 없어야 하며, 하나라도 있으면 ERR_REQUIRE_ASYNC_MODULE 오류가 납니다. 조건을 만족하면 require()는 import()와 같은 모양의 모듈 네임스페이스 객체(module namespace object)를 동기적으로 돌려줍니다. 지금 쓰는 Node.js가 이 기능을 지원하는지는 Node.js 문서에 나온 대로 process.features.require_module이 true인지로 확인할 수 있습니다.
Jest의 24.9 조건도 같은 오류와 이어져 있습니다. 이전 안내는 그보다 낮은 Node.js에서 Jest가 NestJS 12 패키지를 불러오면 ERR_REQUIRE_ASYNC_MODULE로 실패한다고 적고 있습니다. 그래서 같은 컴퓨터에서 애플리케이션은 잘 실행되는데 테스트만 이 오류로 멈춘다면, 코드보다 테스트를 실행한 Node.js의 버전을 먼저 확인합니다.
Nest CLI 준비
Nest CLI는 프로젝트의 뼈대 생성, 구성 요소 생성, 개발 실행과 빌드 명령을 제공합니다. CLI를 실행하는 방법은 두 가지이며, 둘 가운데 하나를 고르면 됩니다. 이 교재는 NestJS 12를 기준으로 하므로 주 버전을 12로 고정한 명령을 씁니다.
공식 문서가 기본 흐름으로 쓰는 방법은 전역 설치입니다.
npm install --global @nestjs/cli@12
nest --help전역 설치는 nest 명령을 어디서나 바로 쓸 수 있어 편하지만, 어떤 버전의 CLI가 실행되는지는 직접 관리해야 합니다. 전역에 설치하지 않으려면 npx로 실행합니다.
npx @nestjs/cli@12 --help프로젝트를 만들 때도 같은 방식을 쓰면 되므로, 전역 nest와 npx 명령을 둘 다 실행할 필요는 없습니다.
첫 NestJS 프로젝트 만들기
프로젝트를 만들 상위 디렉터리에서, 고른 방식에 맞는 명령 하나를 실행합니다. 전역 CLI를 설치했다면 다음과 같습니다.
nest new my-nestjs-app --no-observenew 뒤의 my-nestjs-app은 새로 만들 프로젝트 폴더의 이름이 되고, --no-observe의 뜻은 아래에서 설명합니다. 전역 설치 없이 실행한다면 nest 자리에 npx @nestjs/cli@12를 쓰고, 나머지 인자는 그대로 둡니다.
npx @nestjs/cli@12 new my-nestjs-app --no-observeCLI는 모듈 형식과 사용할 패키지 관리자를 묻고, 선택을 마치면 프로젝트 폴더와 설정 파일, src/의 기본 파일을 만든 뒤 의존성을 설치합니다. 질문의 정확한 문구나 생성 로그의 형식은 CLI 버전에 따라 달라질 수 있으므로 교재의 설명과 한 글자씩 비교하지 않아도 됩니다. 새 프로젝트는 TypeScript의 strict 모드가 켜진 상태로 만들어집니다.
모듈 형식 질문에서 NestJS 12의 기본값은 ESM이며, ESM 프로젝트는 테스트 도구로 Vitest를, CommonJS 프로젝트는 Jest를 씁니다. CommonJS는 require()와 module.exports로 모듈을 주고받는, Node.js가 처음부터 써 온 모듈 형식이며, ESM 패키지와 함께 쓸 때의 규칙은 TypeScript 교재의 CommonJS와의 상호 운용성에서 다룹니다. 이 교재는 확장자 없는 상대 경로 import와 Jest 테스트를 쓰는 CommonJS 구성을 기준으로 하므로, 이 질문에서 CommonJS를 고릅니다. ESM을 골랐다면 ./app.module.js처럼 확장자를 붙인 import와 Vitest 설정에 맞춰야 하므로, 두 방식의 파일을 섞기 전에 package.json과 tsconfig.json을 확인합니다. 어느 형식이든 새 프로젝트에는 린터로 oxlint가 들어갑니다.
명령의 --no-observe는 공식 관측 플랫폼인 NestJS Observe를 연결할지 묻는 질문을 건너뛰고 연결하지 않게 합니다. 대화형 터미널에서는 이 질문의 기본값이 '예'이지만, 관측 SDK와 앱 키 연결은 첫 Hello World! 응답에 필요하지 않습니다. 관측 기능을 쓰고 싶다면 나중에 공식 관측 문서를 따라 따로 준비합니다.
프로젝트를 만든 뒤에는 프로젝트 폴더에서 npm ls @nestjs/core @nestjs/common @nestjs/cli로 실제 설치된 주 버전이 12인지 확인하고, 잠금 파일을 함께 보관합니다. CommonJS를 골랐다고 NestJS의 주 버전이 정해지는 것은 아니므로, 버전은 명령의 @12와 설치 결과로 따로 확인합니다.
프로젝트 실행과 확인
생성된 프로젝트 폴더로 이동해 개발용 스크립트를 실행합니다. 폴더 이름은 new에 넘긴 my-nestjs-app입니다. 상위 디렉터리에 머문 채 실행하면 npm이 이 프로젝트의 package.json을 읽지 않으므로 start:dev 스크립트를 찾지 못합니다.
cd my-nestjs-app
npm run start:devstart:dev는 생성된 package.json의 스크립트이며, 프로젝트에 설치된 로컬 Nest CLI를 씁니다. 파일 변경을 감시하다가 애플리케이션을 다시 컴파일해 실행하므로, 프로젝트를 만들 때 쓴 전역 CLI와 개발 서버를 실행하는 CLI는 구분해야 합니다.
고정된 날짜, 프로세스 ID, 로그 문구 대신 다음을 확인합니다. 명령을 package.json이 있는 프로젝트 폴더에서 실행했는지, 터미널에 처리되지 않은 예외 없이 애플리케이션이 HTTP 요청을 기다리는지, src/main.ts에 정한 포트와 브라우저에서 연 포트가 같은지를 봅니다. 뼈대를 바꾸지 않았다면 http://localhost:3000/에서 Hello World! 응답을 볼 수 있고, PORT 환경 변수로 포트를 바꿨다면 그 포트로 접속해야 합니다.
Nest 개발 서버에서 첫 HTTP 응답까지
프로젝트 script·로컬 CLI watch·main listener·브라우저 route 응답의 실제 실행 경계이다.
Nest 개발 실행 · 로컬 CLI와 HTTP
프로젝트 script가 로컬 CLI를 실행하고, listener의 응답을 확인합니다
package.json이 있는 폴더에서 시작합니다. Nest CLI가 watch·컴파일·재실행을 맡고, main.ts가 정한 포트와 controller route가 브라우저 주소의 기준이 됩니다.
- 프로젝트 폴더 확인
package.json과src/main.ts가 있는 생성된 앱 폴더로 이동한다. - 개발 script 실행
npm run start:dev는 프로젝트에 설치된 로컬 Nest CLI를 호출한다. - 애플리케이션 부팅
Nest CLI가 변경을 감시하고 다시 컴파일하며,
main.ts에 정의된 포트에서 HTTP 요청을 기다린다. - HTTP 응답 확인
브라우저에서 설정된 포트의 기본 route를 열어 응답을 확인한다.
package.json, 부팅하지 못하면 터미널 예외와 포트, 부팅했지만 응답이 다르면 URL과 controller route를 확인한다.이 예의 조건
- 두 박스는 같은 실행의 진행 정보와 자료·결과를 관찰하는 고정 역할입니다. 박스의 좌우·위아래 위치를 별도 호출 순서로 해석하지 않습니다.
- 조건별 종료는 대안입니다. 실패 뒤 정상 후속 단계를 실행하거나 독립 비교 사례를 같은 요청으로 연결하지 않습니다.
- package.json이 있는 프로젝트 폴더에서 start:dev script를 실행하면 프로젝트의 로컬 Nest CLI가 애플리케이션을 감시하고 다시 컴파일해 실행한다. main.ts의 HTTP listener가 설정된 포트에서 브라우저 요청을 받아 기본 route 응답을 반환한다.
- 프로젝트의 package.json 스크립트가 로컬 Nest CLI를 실행한다. CLI가 컴파일과 감시를 맡고 main.ts가 정한 리스너로 요청을 보내 응답을 확인한다.
| 장면 | 관찰 값 | 전환 이유 |
|---|---|---|
| 프로젝트 script package.json 폴더에서 start:dev를 실행합니다. | 입력: 프로젝트 script · CLI: local Nest | 프로젝트 도구가 개발 실행을 시작합니다. |
| watch·listen CLI가 다시 컴파일·실행하고 main listener를 엽니다. | 상태: watch·컴파일 · listener: 설정 포트 | 브라우저 요청을 받을 준비가 됩니다. |
| 기본 route 응답 브라우저 요청에 기본 route가 응답합니다. | 증거: HTTP 응답 · 대상: 기본 route | 개발 실행이 실제 요청까지 도달합니다. |
Nest 개발 서버에서 첫 HTTP 응답까지
프로젝트 script·로컬 CLI watch·main listener·브라우저 route 응답의 실제 실행 경계이다.
Nest 개발 실행 · 로컬 CLI와 HTTP
프로젝트 script가 로컬 CLI를 실행하고, listener의 응답을 확인합니다
package.json이 있는 폴더에서 시작합니다. Nest CLI가 watch·컴파일·재실행을 맡고, main.ts가 정한 포트와 controller route가 브라우저 주소의 기준이 됩니다.
- 프로젝트 폴더 확인
package.json과src/main.ts가 있는 생성된 앱 폴더로 이동한다. - 개발 script 실행
npm run start:dev는 프로젝트에 설치된 로컬 Nest CLI를 호출한다. - 애플리케이션 부팅
Nest CLI가 변경을 감시하고 다시 컴파일하며,
main.ts에 정의된 포트에서 HTTP 요청을 기다린다. - HTTP 응답 확인
브라우저에서 설정된 포트의 기본 route를 열어 응답을 확인한다.
package.json, 부팅하지 못하면 터미널 예외와 포트, 부팅했지만 응답이 다르면 URL과 controller route를 확인한다.이 예의 조건
- 두 박스는 같은 실행의 진행 정보와 자료·결과를 관찰하는 고정 역할입니다. 박스의 좌우·위아래 위치를 별도 호출 순서로 해석하지 않습니다.
- 조건별 종료는 대안입니다. 실패 뒤 정상 후속 단계를 실행하거나 독립 비교 사례를 같은 요청으로 연결하지 않습니다.
- package.json이 있는 프로젝트 폴더에서 start:dev script를 실행하면 프로젝트의 로컬 Nest CLI가 애플리케이션을 감시하고 다시 컴파일해 실행한다. main.ts의 HTTP listener가 설정된 포트에서 브라우저 요청을 받아 기본 route 응답을 반환한다.
- 프로젝트의 package.json 스크립트가 로컬 Nest CLI를 실행한다. CLI가 컴파일과 감시를 맡고 main.ts가 정한 리스너로 요청을 보내 응답을 확인한다.
| 장면 | 관찰 값 | 전환 이유 |
|---|---|---|
| 프로젝트 script package.json 폴더에서 start:dev를 실행합니다. | 입력: 프로젝트 script · CLI: local Nest | 프로젝트 도구가 개발 실행을 시작합니다. |
| watch·listen CLI가 다시 컴파일·실행하고 main listener를 엽니다. | 상태: watch·컴파일 · listener: 설정 포트 | 브라우저 요청을 받을 준비가 됩니다. |
| 기본 route 응답 브라우저 요청에 기본 route가 응답합니다. | 증거: HTTP 응답 · 대상: 기본 route | 개발 실행이 실제 요청까지 도달합니다. |
그림은 package.json이 있는 폴더에서 npm run start:dev를 실행하면 프로젝트의 로컬 Nest CLI가 감시와 재컴파일을 맡고, main.ts의 HTTP 리스너가 설정한 포트에서 브라우저 요청을 받아 기본 경로의 응답을 돌려주는 흐름입니다. 명령을 찾지 못하면 현재 폴더와 package.json을, 부팅하지 못하면 터미널의 예외와 포트를, 부팅했는데 응답이 다르면 URL과 컨트롤러의 경로를 확인합니다.
정리
- NestJS 12는 실행에 Node.js 20.19 이상을, CLI의 생성 명령에 22.22.3·24.15·26 이상 가운데 하나를 요구하며, 이 교재는 Node.js 24 LTS(24.15 이상)를 기준으로 합니다.
- CLI는 전역 설치와
npx가운데 하나로 실행하고, 이 교재는 주 버전을@12로 고정합니다. - 새 프로젝트를 만들 때 모듈 형식은 CommonJS를 골라 Jest를 쓰고,
--no-observe로 관측 연결 질문을 건너뜁니다. - 개발 서버는 프로젝트의 로컬 CLI로 실행하며, 로그 문구보다 설정한 포트의 실제 응답으로 확인합니다.
연습 문제
1. 막힌 위치 찾기
node --version과 CLI 도움말은 정상인데, npm run start:dev에서 package.json을 찾을 수 없다는 오류가 납니다. Node.js를 다시 설치하기 전에 무엇을 확인해야 하나요? 반대로 서버 시작 로그가 나온 뒤 브라우저에서 연결할 수 없다면 무엇을 비교해야 하나요?
해설 보기
첫 경우에는 생성된 my-nestjs-app 폴더로 이동했는지 확인합니다. npm은 현재 폴더에 있는 프로젝트의 스크립트를 실행하므로, CLI 설치가 정상이어도 다른 폴더에서는 그 스크립트를 찾지 못합니다.
두 번째 경우에는 main.ts의 포트, PORT 환경 변수, 브라우저 주소를 비교하고, 서버 프로세스가 아직 실행 중인지 확인합니다. 시작 로그를 한 번 보았다는 사실만으로 지금의 HTTP 응답까지 확인한 것은 아닙니다.
2. Node.js 버전 고르기
네 대의 컴퓨터에 각각 Node.js 20.19, 22.20, 24.12, 26.13이 설치되어 있습니다. 각 컴퓨터에서 NestJS 12 애플리케이션 실행, nest new 실행, Jest로 NestJS 12 패키지를 불러오는 테스트 실행이 가능한지 표로 정리하세요.
해설 보기
애플리케이션 실행은 20.19 이상(22.x는 22.12 이상)이면 되므로 네 대 모두 가능합니다. nest new는 22.22.3, 24.15, 26 이상 가운데 하나를 요구하므로 26.13만 가능하며, 22.20과 24.12는 각 계열의 최소 버전보다 낮고 20.19는 해당 계열이 없습니다.
Jest가 ESM 전용인 NestJS 12 패키지를 불러오려면 24.9 이상이 필요하므로 24.12와 26.13만 가능합니다. 같은 컴퓨터라도 하려는 일에 따라 조건이 다르므로, 세 조건을 모두 만족하는 24.15 이상이나 26 LTS로 맞추는 편이 단순합니다.
3. 모듈 형식과 import 표기
CommonJS 구성을 따라 쓴 import { AppModule } from './app.module';을, ESM으로 만든 프로젝트의 main.ts에 그대로 넣으면 어떻게 되나요? 프로젝트가 어느 모듈 형식인지는 어디에서 확인하나요?
해설 보기
CLI가 만드는 두 형식의 tsconfig.json은 모두 module과 moduleResolution을 nodenext로 둡니다. nodenext에서는 package.json의 "type"이 "module"인 프로젝트의 파일을 ECMAScript 모듈로 다루고, ECMAScript 모듈의 상대 경로 import에는 확장자가 있어야 합니다. 그래서 TypeScript가 컴파일할 때 상대 경로에 명시적인 확장자가 필요하다는 오류를 내며, ./app.module.js로 고쳐야 합니다. CommonJS 프로젝트에서는 같은 설정이라도 CommonJS 해석 규칙이 적용되어 확장자 없이 쓸 수 있습니다.
프로젝트의 모듈 형식은 package.json의 "type" 필드로 확인합니다. "module"이면 ESM이고, 이 필드가 없거나 "commonjs"이면 CommonJS입니다. 교재의 예제를 옮길 때는 이 형식에 맞춰 import 표기와 테스트 도구를 함께 맞춥니다.
다음 글 첫 번째 NestJS 애플리케이션 만들기에서는 생성된 main.ts, 모듈, 컨트롤러, 서비스가 첫 요청을 어떻게 처리하는지 따라가 봅니다.