npmで各パッケージのバージョン番号を固定してインストールする仕組みがあるのだろうかと調べてみたら、shrinkwrapという機能があった。

説明書

  • https://docs.npmjs.com/cli/shrinkwrap
    • npm installするにはpackage.jsonも必要
    • npm shrinkwrapするとnpm-shrinkwrap.jsonが生成され、各パッケージのバージョン番号が記録される
    • npm-shrinkwrap.jsonをgitに追加しておくと、別の環境でnpm installした時にも同じバージョンのパッケージをインストールできる
    • npm install foo --saveするとnpm-shrinkwrap.jsonにもfooが追加される
    • npm uninstall foo --saveするとnpm-shrinkwrap.jsonからfooが削除される
    • npm shrinkwrap --devするとdevDependenciesも記録対象になる

使ってみた

npmのバージョン。

$ node -v
v6.9.1
$ npm -v
3.10.8

試しに使ってみた例がこちら。

$ npm install jquery@3.0.0 --save
shrinkwrap-test@1.0.0 /home/vagrant/work/shrinkwrap-test
└── jquery@3.0.0
$ npm shrinkwrap
wrote npm-shrinkwrap.json
$ npm install jquery-ui@1.12.0 --save
wrote npm-shrinkwrap.json
shrinkwrap-test@1.0.0 /home/vagrant/work/shrinkwrap-test
└── jquery-ui@1.12.0
$ cat npm-shrinkwrap.json
{
"name": "shrinkwrap-test",
"version": "1.0.0",
"dependencies": {
"jquery": {
"version": "3.0.0",
"from": "jquery@3.0.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.0.0.tgz"
},
"jquery-ui": {
"version": "1.12.0",
"from": "jquery-ui@1.12.0",
"resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.0.tgz"
}
}
}

shrinkwrapを有効にしている場合、npm install時に、次のメッセージが出てくるようだ。

wrote npm-shrinkwrap.json

バージョンの固定

別ディレクトリにpackage.jsonとnpm-shrinkwrap.jsonをコピーしてnpm installしてみる。

$ ls
npm-shrinkwrap.json package.json
$ npm outdated
Package Current Wanted Latest Location
jquery 3.0.0 3.1.1 3.1.1 shrinkwrap-test
jquery-ui 1.12.0 1.12.1 1.12.1 shrinkwrap-test
$ npm install
shrinkwrap-test@1.0.0 /home/vagrant/work/shrinkwrap-test2
├── jquery@3.0.0
└── jquery-ui@1.12.0

最新版のjquery@3.1.1、jquery-ui@1.12.1ではなく、それぞれ3.0.0、1.12.0がインストールされた。