Help us understand the problem. What is going on with this article?

npm shrinkwrapを運用で使うためのコツ

More than 3 years have passed since last update.

npm shrinkwrap とは?

npm shrinkwrapは、Node.jsプロジェクトの依存モジュールのバージョンを固定するコマンドです。
使い方についてはこちらの記事が参考になります。

今回は、npm shrinkwrapより安定して使うためのコツを記載しました。

1. CIを活用し、テストしたバージョンで固定しリリース

npm shrinkwrapコマンドではnpm-shrinkwrap.jsonというファイルが生成されます。
継続的インテグレーションのサービスを活用し、そこでテストしたバージョンで固定するとよいでしょう。
CIでのフローとすれば以下になると思います。

  1. npm updateで、可能な限り新しいバージョンを利用
  2. テスト (npm test)
  3. npm shrinkwrap
  4. npm-shrinkwrap.jsonを追加しコミット、別tagや別branchとしてpushする (リリース)

テストされた依存モジュールのバージョンを配布できるので、安定度が上がります。
またリリースtag, branchだけにnpm-shrinkwrap.jsonを作ることで、
開発ブランチでのpackage.jsonnpm-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を利用)

  1. npm update
  2. npm test
  3. npm prune --production
  4. npm shrinkwrap
  5. git add npm-shrinkwrap.json
  6. git commit -m "vX.Y.Z"
  7. git tag vX.Y.Z
  8. git push origin vX.Y.Z

(5-8はgitでtagをリリースする一例です)

↑を楽にやるライブラリ

CircleCIで、これを楽にやるnode-circleci-autoreleaseを作成しました。ぜひ利用してみてください。

CureApp/node-circleci-autorelease

shrinkwrapだけでなく、gh-pagesnpm publishなど、リリース自動化周辺の操作を設定ファイル1つで管理できます。
次回、日本語で使い方の解説記事を書きます。

shinout
CureAppの中の人。 マルチプラットフォーム、Universal JSのことに関心あり。
https://cureapp.co.jp/
cureapp
医学的エビデンスに基づいた医療機器プログラム『治療アプリ』を開発しています。
https://cureapp.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away