これは、なにをしたくて書いたもの?
Node.jsでモジュールをインストールするコマンドとしてnpm install
(エイリアスnpm i
、npm add
)があるわけですが、
npm ci
がどういうものだったかよく忘れるのでメモしておきます。
ちょっとドキュメントを眺めてみましょう。
環境
今回の環境は、こちら。
$ node --version v16.13.1 $ npm --version 8.1.2
というわけで、npm v8のドキュメントを見ていきます。
npm ci
npm ci
のドキュメントはこちら。
npm ci
は、npm install
に似たコマンドです。CI環境やテスト環境での利用、依存関係のクリーンインストールを行う場合に
使用します。
特徴は、以下です。
- プロジェクトは
package-lock.json
はnpm-shrinkwrap.json
のどちらかを保持している必要がある package.json
と、package-lock.json
(またはnpm-shrinkwrap.json
)の間に一致しない依存関係がある場合、npm ci
は失敗するnpm install
は、このパターンではpackage-lock.json
を更新する
- プロジェクト全体の依存関係がインストール可能で、個別の依存関係を追加は不可
node_modules
ディレクトリが存在する場合は、npm ci
の実行前に自動的に削除されるpackage.json
やpackage-lock.json
ファイルへの更新は行われず、インストール対象のパッケージバージョンは凍結される
npm install
npm install
のドキュメントは、こちら。
npm install
は、以下のファイルの優先順位に従って動作します。
npm-shrinkwrap.json
package-lock.json
yarn.lock
npm install [パッケージ]
1番よく使うものかなと。パッケージについてはこちらに書かれており、npmレジストリに存在するもの以外に、
tar.gzやフォルダも使えることになっています。
About packages and modules / About packages
このコマンドは、指定されたパッケージをローカルのnode_modules
ディレクトリにインストールします。
以下の指定方法では、latest
タグに相当するバージョンがインストールされ、dependencies
(-D
または--save-dev
を
使った場合はdevDependencies
)に追加されます。
$ npm install [<@scope>/]<name>
この時、package-lock.json
も更新されます。
その他の指定パターン(※)については、ドキュメントを参照…。
※このあたりですね
npm install [<@scope>/]<name>@<version>
npm install [<@scope>/]<name>@<version range>
npm install [<@scope>/]<name>@<tag>
npm install [Git URL、GitHub、BitBucket等]
npm install(引数なし)
依存関係をローカルのnode_modules
ディレクトリにインストールします。
※-g
または--global
オプションが付与されている場合は、カレントディレクトリをグローバルとして扱ってインストール
デフォルトでは、package.json
に記述されているすべての依存関係がインストールされます。
--production
オプションまたは環境変数NODE_ENV
にproduction
が設定されている場合は、devDependencies
に
記述されている依存関係はインストールされません。
NODE_ENV
環境変数をproduction
に設定している場合でもdependencies
とdevDependencies
の両方をインストールする
場合は、--production=false
とオプションに指定すればよいみたいです。
ちなみに、--production
オプションは依存関係の追加時には効果がありません。
--production flag has no particular meaning when adding a dependency to a project.`
npm install [ディレクトリ]
現在のプロジェクトへのシンボリックリンクとして、パッケージをインストールします。
対象のパッケージに依存関係がある場合は、シンボリックリンク作成前にインストールされます。
npm install [tarファイル]
ファイルシステム上にあるパッケージをインストールします。
ちょっと試してみる
簡単に試してみましょう。
Node.jsプロジェクトを作成して
$ npm init -y
以下の依存関係をインストール。
$ npm i -D typescript $ npm i -D -E prettier $ npm i -D jest @types/jest ts-jest $ npx ts-jest config:init $ npm i express $ npm i -D @types/node@v16 @types/express
こうなります。
$ ll package*.json -rw-rw-r-- 1 xxxxx xxxxx 310127 1月 4 15:56 package-lock.json -rw-rw-r-- 1 xxxxx xxxxx 582 1月 4 15:56 package.json
依存関係は、これだけですね。
"devDependencies": { "@types/express": "^4.17.13", "@types/jest": "^27.4.0", "@types/node": "^16.11.18", "jest": "^27.4.5", "prettier": "2.5.1", "ts-jest": "^27.1.2", "typescript": "^4.5.4" }, "dependencies": { "express": "^4.17.2" }
npm ls
で確認。
$ npm ls project@1.0.0 /path/to/project ├── @types/express@4.17.13 ├── @types/jest@27.4.0 ├── @types/node@16.11.18 ├── express@4.17.2 ├── jest@27.4.5 ├── prettier@2.5.1 ├── ts-jest@27.1.2 └── typescript@4.5.4
1度、node_modules
ディレクトリを削除します。
$ rm -rf node_modules
npm i
(npm install
)。
$ npm i
依存関係は変わっていませんが、package-lock.json
は更新されます。
$ npm ls project@1.0.0 /path/to/project ├── @types/express@4.17.13 ├── @types/jest@27.4.0 ├── @types/node@16.11.18 ├── express@4.17.2 ├── jest@27.4.5 ├── prettier@2.5.1 ├── ts-jest@27.1.2 └── typescript@4.5.4 $ ll package*.json -rw-rw-r-- 1 xxxxx xxxxx 310127 1月 4 16:34 package-lock.json -rw-rw-r-- 1 xxxxx xxxxx 582 1月 4 15:56 package.json
npm ci
を実行してみます。
$ npm ci
こちらは、package-lock.json
は更新されません。
$ npm ls project@1.0.0 /path/to/project ├── @types/express@4.17.13 ├── @types/jest@27.4.0 ├── @types/node@16.11.18 ├── express@4.17.2 ├── jest@27.4.5 ├── prettier@2.5.1 ├── ts-jest@27.1.2 └── typescript@4.5.4 $ ll package*.json -rw-rw-r-- 1 xxxxx xxxxx 310127 1月 4 16:34 package-lock.json -rw-rw-r-- 1 xxxxx xxxxx 582 1月 4 15:56 package.json
npm ci
にも--production
は指定できるみたいですね。
$ npm ci --production
npm ls
すると、devDependencies
の分は不足扱いになってしまいますが。
$ npm ls project@1.0.0 /path/to/project ├── UNMET DEPENDENCY @types/express@^4.17.13 ├── UNMET DEPENDENCY @types/jest@^27.4.0 ├── UNMET DEPENDENCY @types/node@^16.11.18 ├── express@4.17.2 ├── UNMET DEPENDENCY jest@^27.4.5 ├── UNMET DEPENDENCY prettier@2.5.1 ├── UNMET DEPENDENCY ts-jest@^27.1.2 └── UNMET DEPENDENCY typescript@^4.5.4 npm ERR! code ELSPROBLEMS npm ERR! missing: @types/express@^4.17.13, required by npm-ci-test@1.0.0 npm ERR! missing: @types/jest@^27.4.0, required by npm-ci-test@1.0.0 npm ERR! missing: @types/node@^16.11.18, required by npm-ci-test@1.0.0 npm ERR! missing: jest@^27.4.5, required by npm-ci-test@1.0.0 npm ERR! missing: prettier@2.5.1, required by npm-ci-test@1.0.0 npm ERR! missing: ts-jest@^27.1.2, required by npm-ci-test@1.0.0 npm ERR! missing: typescript@^4.5.4, required by npm-ci-test@1.0.0 npm ERR! A complete log of this run can be found in: npm ERR! $HOME/.npm/_logs/2022-01-04T07_39_03_323Z-debug.log
もう1度、node_modules
ディレクトリを削除。
$ rm -rf node_modules
npm install
。
$ npm i $ npm ls project@1.0.0 /path/to/project ├── @types/express@4.17.13 ├── @types/jest@27.4.0 ├── @types/node@16.11.18 ├── express@4.17.2 ├── jest@27.4.5 ├── prettier@2.5.1 ├── ts-jest@27.1.2 └── typescript@4.5.4
npm install --production
でも、ここからdependencies
のみの状態にできるようですが
$ npm i --production $ npm ls project@1.0.0 /path/to/project ├── UNMET DEPENDENCY @types/express@^4.17.13 ├── UNMET DEPENDENCY @types/jest@^27.4.0 ├── UNMET DEPENDENCY @types/node@^16.11.18 ├── express@4.17.2 ├── UNMET DEPENDENCY jest@^27.4.5 ├── UNMET DEPENDENCY prettier@2.5.1 ├── UNMET DEPENDENCY ts-jest@^27.1.2 └── UNMET DEPENDENCY typescript@^4.5.4 npm ERR! code ELSPROBLEMS npm ERR! missing: @types/express@^4.17.13, required by npm-ci-test@1.0.0 npm ERR! missing: @types/jest@^27.4.0, required by npm-ci-test@1.0.0 npm ERR! missing: @types/node@^16.11.18, required by npm-ci-test@1.0.0 npm ERR! missing: jest@^27.4.5, required by npm-ci-test@1.0.0 npm ERR! missing: prettier@2.5.1, required by npm-ci-test@1.0.0 npm ERR! missing: ts-jest@^27.1.2, required by npm-ci-test@1.0.0 npm ERR! missing: typescript@^4.5.4, required by npm-ci-test@1.0.0 npm ERR! A complete log of this run can be found in: npm ERR! $HOME/.npm/_logs/2022-01-04T07_46_41_347Z-debug.log
やっぱりpackage-lock.json
は更新されます。
$ ll package*.json -rw-rw-r-- 1 xxxxx xxxxx 310127 1月 4 16:47 package-lock.json -rw-rw-r-- 1 xxxxx xxxxx 582 1月 4 15:56 package.json
というわけで、単にプロジェクトで定義されている依存関係をインストールしたいだけなら、npm ci
を使った方が
よい感じがしますね。