概要
npm run startを実行したらどんな流れで起動しているのだろう?
と思い、調べてみました。
NestJS CLIの仕組み
nest コマンドの正体
npm run start を実行すると、内部では以下のコマンドが走ります。
nest start
では、なぜ
npm run start が nest start を呼ぶの?
というと、package.json の scripts にそう書かれているからです。
// package.json
{
"scripts": {
"start": "nest start"
}
}
この nest の実体は、プロジェクトの node_modules/.bin/nest にある実行ファイルです。
プロジェクト/
node_modules/
.bin/
nest ← @nestjs/cli/bin/nest.js へのシンボリックリンク
@nestjs/
cli/ ← NestJS CLIのソースコード
npm install したときに @nestjs/cli パッケージがインストールされ、その package.json の bin フィールド({"nest": "bin/nest.js"})を元に、.bin/nest が自動生成されます。
参考:
なぜ nest-cli.json を自動で読むのか
nest コマンド自体が NestJS CLI のプログラムであり、実行時に自動で設定ファイルを探して読むように作られているからです。
CLI内部の設定ローダーは、カレントディレクトリから以下のファイル名を順に探します。
// @nestjs/cli/lib/configuration/nest-configuration.loader.ts
: this.reader.readAnyOf([
'nest-cli.json',
'.nest-cli.json',
]);
(見つからなければ内蔵のデフォルト値が使われるので、nest-cli.json は実は必須ではないらしい)
起動の流れ
nest start は src/main.ts を直接実行しているわけではありません。
ビルドしてから、生成されたJSファイルを node で実行しています。
npm run start
↓ npm が node_modules/.bin を PATH に追加
nest start
↓ nest-cli.json を読む
↓ tsconfig.json の outDir を読む(未指定なら dist)
↓ deleteOutDir: true なら dist/ を削除
↓ tsc でビルド → dist/ にJSを出力
↓ dist/ 配下の main.js を実行
node --enable-source-maps dist/src/main.js
実行するファイルは dist/<sourceRoot>/main.js を優先し、無ければ dist/main.js にフォールバックします。ビルド成果物が dist/src/main.js になるか dist/main.js になるかは tsconfig の設定で変わるため、CLI側が2段構えで吸収しています。
参考:
In addition to the shell's pre-existing
PATH,npm runaddsnode_modules/.binto thePATHprovided to scripts.
npm Docs — npm run-script
nest-cli.json の役割
// nest-cli.json
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}
主なフィールドの意味:
| フィールド | デフォルト | 意味 |
|---|---|---|
sourceRoot |
"src" |
ソースのルートディレクトリ。実行パスのディレクトリ部分に使われる |
collection |
"@nestjs/schematics" |
nest generate コマンドで使うテンプレート集(通常は変更不要) |
compilerOptions.deleteOutDir |
false |
ビルド前に出力先(dist/)を毎回削除するかどうか |
sourceRoot はデフォルト値を持つため、nest-cli.json から消しても src として扱われます。なお出力先の dist は nest-cli.json ではなく tsconfig.json の outDir 側の設定です。
参考:
-
NestJS Docs — CLI: Workspaces —
nest-cli.jsonのプロパティ一覧
まとめ
| 要素 | 正体 |
|---|---|
nest コマンド |
node_modules/.bin/nest(@nestjs/cli が提供)。npm scripts が .bin を PATH の先頭に通すので、名前だけで解決できる |
nest-cli.json |
CLIがカレントディレクトリから自動で読む設定ファイル。任意で、無ければデフォルト値が使われる |
sourceRoot |
ソースのディレクトリ(デフォルト src)。実行パスのディレクトリ部分 |
outDir |
コンパイル結果の出力先。nest-cli.json ではなく tsconfig.json 側の設定で、CLIは実行パスの起点としてこれを読む |
npm install → @nestjs/cli インストール → .bin/nest が生成される → npm scripts から nest コマンドが使える、という順番で環境が整います。