npm shrinkwrap とは?
npm shrinkwrap
は、Node.jsプロジェクトの依存モジュールのバージョンを固定するコマンドです。
使い方についてはこちらの記事が参考になります。
今回は、npm shrinkwrap
をより安定して使うためのコツを記載しました。
1. CIを活用し、テストしたバージョンで固定しリリース
npm shrinkwrap
コマンドではnpm-shrinkwrap.json
というファイルが生成されます。
継続的インテグレーションのサービスを活用し、そこでテストしたバージョンで固定するとよいでしょう。
CIでのフローとすれば以下になると思います。
-
npm update
で、可能な限り新しいバージョンを利用 - テスト (
npm test
) npm shrinkwrap
-
npm-shrinkwrap.json
を追加しコミット、別tagや別branchとしてpushする (リリース)
テストされた依存モジュールのバージョンを配布できるので、安定度が上がります。
またリリースtag, branchだけにnpm-shrinkwrap.json
を作ることで、
開発ブランチでのpackage.json
とnpm-shrinkwrap.json
の二重管理の問題もなくなります。
2. devDependencies周りのバグを理解し、克服する
devDependencies
は、開発のみに必要でproductionには必要ない依存モジュール群です。
これらをnpm-shrinkwrap.json
から省くことで、インストール速度が向上します。
公式ドキュメントには、devDependenciesは入らないと書いていますが、
npm v3はバグがあり、devDependenciesがいくつか混じってしまいます。
さらに興味深いことに、npm v2では別のバグがあり、必要なdependenciesが入らない状況があります。
(see https://github.com/npm/npm/issues/11189)
npm v3の場合
npm shrinkwrap
は不必要なdevDependenciesを含んでしまいます。
gistに再現コードを載せました。
ソースは追っていませんが、devDependenciesのdependenciesが含まれるような結果になっています。
npm v2の場合
一方npm v2ではdevDependenciesをしっかり除去してくれます!
しかし、逆に必要なモジュールが入らない状況があります。
gistに再現コードを載せました。
devDependenciesを除去するときに、それがdependenciesのdependenciesであっても取り除くようになっています。
じゃあどうするか?
このままではproductionで安定して使う気になれません。
そこで、運用では下記のような操作を行うことでこのバグを克服することにしました。
rm -rf node_modules
npm install --production
npm shrinkwrap
こうすることで、npm v2およびv3において、必要十分なモジュールのみが書き込まれます。
しかし残念なことに、これだとテストしたバージョンでshrinkwrapできない問題があります...
そこでnpm v3限定であれば以下のコマンドも利用可能です。
npm prune --production
npm shrinkwrap
npm prune
によってproductionに必要ないモジュールが取り除かれるため、うまくいきます。
まとめ
-
npm-shrinkwrap.json
をCIで作って自動リリースがよい -
devDependencies
関連にバグがあることを理解し、それを乗り越える
結局どうするの
CIなどで下記のような順番でコマンドを実行するといいでしょう。
(npm v3を利用)
npm update
npm test
npm prune --production
npm shrinkwrap
git add npm-shrinkwrap.json
git commit -m "vX.Y.Z"
git tag vX.Y.Z
git push origin vX.Y.Z
(5-8はgitでtagをリリースする一例です)
↑を楽にやるライブラリ
CircleCIで、これを楽にやるnode-circleci-autoreleaseを作成しました。ぜひ利用してみてください。
CureApp/node-circleci-autorelease
shrinkwrap
だけでなく、gh-pages
やnpm publish
など、リリース自動化周辺の操作を設定ファイル1つで管理できます。
次回、日本語で使い方の解説記事を書きます。