これまで npm shrinkwrap
使っていなかったんだけど、プライベートでやっているプロダクトで使うようにしたのでメモ。
3行まとめ
npm shrinkwrap
するとnpm-shrinkwrap.json
が生成される- npm 3系では
npm-shrinkwrap.json
にdeependencies
のパッケージは記載されているが、devDependencies
のパッケージは記載されないのがデフォルトの挙動。devDependencies
を含めるには--dev
オプションを付ける - npm@4.0.1 からは
npm-shrinkwrap.json
にdevDeependencies
のパッケージを含めるのがデフォルトの挙動。除外するには--production
オプションを付ける
きっかけ
サーバーを移設した際に新しいサーバーで npm install
したらパッケージ間の依存関係が壊れた。同様のことはこれまでにたしか 2回ほどあって、3回目のときにはカイゼンしようと心に決めていたのでやった。
$ npm install ... npm WARN xxx requires a peer of yyy but none was installed.
どうして Yarn ではないのか?
Yarn を使ってもパッケージのバージョンを固定してくれるので、今回の問題に対してそれでも解決できたのだけれど。
しかし Yarn は別のプロジェクトで使っていて、つまり経験があるので、経験が無いほうの npm shrinkwrap
という手段を選んだ。何かしらのヒントが得られるかもしれないと思って。
環境
手元の Mac の環境。ただし、後述するが npm のバージョンは途中で上げた。
$ node --version v6.9.5 $ npm --version 3.10.10
ドキュメント
公式ドキュメント にざっと目を通した。日本語訳 もあったが、内容が古かったため。
事始め
node_modules を一旦真っ新にしてから npm shrinkwrap
した。
$ rm -rf node_modules $ npm install $ npm shrinkwrap wrote npm-shrinkwrap.json
npm-shrinkwrap.json
が生成されたので git commit した。
ただし、この時点では npm-shrinkwrap.json
に deependencies
のパッケージは記載されているが、devDependencies
のパッケージは記載されていない(重要)
devDependencies も含めてバージョン固定する
どうして npm-shrinkwrap.json
に devDependencies
のパッケージに含めないのがデフォルトの仕様なんだろう?複数の開発環境や CI の間で devDependencies
パッケージのバージョンを揃えたいというのが自分の考えるフツウなのだが(Ruby の Bundler もそうだし)
ともあれ --dev
オプションを付ければ devDependencies
のパッケージも含められるとのことなので実行。
$ npm shrinkwrap --dev
npm@4.0.1 からは devDependencies のパッケージも含めるのがデフォルト
なお 公式ドキュメント や リリースノート にもあるように、npm のバージョン 4.0.1
からは npm-shrinkwrap.json
に devDependencies
のパッケージに含めるのがデフォルトの挙動になった(含めたくない場合は --production
オプションを付ける)
ついでなので npm のバージョンを 4系に上げた。
$ npm install --global npm@4 $ npm --version 4.5.0
おまけ)npm 4系で npm-shrinkwrap.json を作り直した
npm のバージョンを 4系に上げて、何か挙動が変わっただろうかという確認のため、やり直してみた。
$ rm -rf node_modules $ rm npm-shrinkwrap.json $ npm install $ npm shrinkwrap wrote npm-shrinkwrap.json
差分を見る。
[@ANGELINA.local maskedgirl-ui]$ git diff diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 167b0e76..b136f399 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -6015,7 +6015,7 @@ }, "sinon": { "version": "2.2.0", - "from": "sinon@latest", + "from": "sinon@>=2.2.0 <3.0.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.2.0.tgz", "dev": true, "dependencies": {
なんだこれ。まさに、という記事を見つけた。
詳しくは上の記事の通りだが、今回 npm-shrinkwrap.json の差分が出たのは npm のバージョンを上げた影響ではなかった(記事を見ながら、ソースを追ってみたが、from
の出力に関する箇所は npm@3.10.10 と npm@4.5.0 に差異はなかった)
まとめ
Yarn と較べて。Yarn は yarn install
すれば yarn.lock
も自動で生成されるのに対し、npm install
と npm shrinkwrap
が分かれている点が少し馴染めない。コマンドを打つのが面倒というより npm-shrinkwrap.json
を意識せずに過ごしたいんだよなあ。
ともあれ npm パッケージのバージョン固定に成功した。めでたい。