綺麗に死ぬITエンジニア

Node.jsでデプロイ時のパッケージのバージョンを固定する方法

2017-03-01

Node.js(JavaScript)で一般的に利用されるパッケージ管理ツール「npm(Node Package Manager)」は、普通に使うと、パッケージのバージョンを固定しません。v5.0.0からはパッケージのバージョンを固定するためのpackage-lock.jsonがデフォルトで出力されるようになりました。v5.0.0以上をお使いの方は、以下の設定はせずとも、パッケージのバージョンは固定されます。

例えば、1月1日に自身のプロジェクトをテストし、1月2日にそのプロジェクトに含まれるパッケージの1つがアップデートされた場合、1月3日にデプロイ作業でnpm installを実行するとすると、1月1日にテストしたパッケージとは違うバージョンのパッケージ(アップデートされた後のパッケージ)がインストールされることになります。

多くの場合、package.jsonでメジャーバージョンは固定しているでしょうから、セマンティックバージョニングの観点から問題にはなりにくいですが、この現象のせいでテストを通過していないソースコードがデプロイされてしまう可能性がゼロではないです。

PHPの場合、一般的なパッケージ管理ツールは「Composer」ですが、Composerの場合はパッケージのバージョンを記述したファイルcomposer.json(npmでいうところのpackage.json)の他に、composer.lockというパッケージのバージョンを完全に固定する役割を持つファイルが生成されるため、問題になることはありません。

今回は、Node.jsの場合においても、デプロイ時のバージョンを固定する方法を紹介します。

サーバーサイドでデプロイ時にnpm installを実行する運用をしている場合、安全にデプロイするためには必須といえるプロセスなので、ある日急に動かなくなることを避けるために、実施しておきましょう。

ユースケース

package.jsonで、バージョン指定に"^1.0.0""~1.0.0""1.*"などと範囲指定している場合、npm install実行した時点での最新バージョンがインストールされます。

つまり、テストから時間が経過していると、テスト時とは違うバージョンのパッケージがインストールされる可能性があります。

この現象を回避します。

npmのshrinkwrapを利用する

npmにはオプションで、バージョン情報を固定する機能があります。

npm installを実施した後に、以下のコマンドを実行します。

npm shrinkwrap

こうすることで、パッケージの厳密なバージョン情報が記載されたnpm-shrinkwrap.jsonファイルが生成されます。

次にnpm installコマンドを実行した際、npmはnpm-shrinkwrap.jsonに記載されたバージョンのパッケージをインストールするようになります。つまり、これをpackage.jsonと一緒にGit等にそのまま登録してしまえば、デプロイ時にバージョンに差異が出ることがなくなります。

Yarnを利用する

他にも、Yarnというnpm(package.json)と互換性のあるパッケージ管理ツールを使う方法があります。

YarnはFacebook、Google、Exponent、Tildeによって開発された比較的新しいJavaScriptパッケージマネージャーです。npmの問題解決を目的としています。

Yarnでは、デフォルトでパッケージのインストール時(yarnもしくはyarn install実行時)にyarn.lockという、パッケージの厳密なバージョン情報が記載されたファイルを生成します。yarn.lockは、ユーザーの操作なしに勝手に更新されることはありません。PHPのComposerでいうところのcomposer.lockファイルのような役割を果たします。

そのため、Yarnを用いてパッケージ管理をすると、デフォルトでバージョンを固定してくれるのです。

なお、package.jsonの内容を元に、各パッケージのバージョン情報を最新に更新し、yarn.lockを更新したい場合は、以下のコマンドを実行すれば実現できます。

yarn upgrade

# 特定のパッケージのみの場合
yarn upgrade [package]

PHPのComposerでいうところのcomposer updateのような位置付けですね。

Yarnは、npmとコマンドの構文は違いますが、同じような感覚でNode.jsのパッケージ管理ができます。詳しい利用方法はこちらに記載があります。

バージョン固定以外にも、パフォーマンスやセキュリティの観点からもYarnはnpmよりも有利とされています。Yarnを利用するのも有効な手段の一つとなるでしょう。

まとめ

npmはデフォルトで、パッケージのバージョン情報を固定しません。v5.0.0からはパッケージのバージョンを固定してくれるようになりました。

固定してくれないと、運用方法によっては、デプロイと同時に急に本番環境が正常に動作しなくなることも考えられます。

普段は問題になりにくい部分なので、今一度確認してみるといいでしょう。

筆者について

フリーランスエンジニアとして活動している、「もりやませーた」です。

筆者のTwitterはこちら。記事に関するご意見等はTwitterの方へお寄せください。

その他業務に関するお問い合わせは、こちらのページをご覧ください。

Linux Node.js