(追記)v8.2.0がリリースされて、npm 5.3.0がバンドルされるようになったので、最新版を使うなら問題なくなりました。
とりあえず、結論
2017/07/18の時点で最新版のnode.js v8.1.4ではnpm v5.0.3がバンドルされているが、特定の状況でnpm installするとインストール済みの必要な依存ライブラリが削除されるので、npmをアップデートしてから使ったほうがよい。(npm v5.2.0では起こらないことを確認済み)
どういう状況で起こるか
すでにライブラリがインストールされている状況で、ライブラリのバージョンを上げた package.json
, package-lock.json
を持ってきて npm install
すると、バージョンが上がったライブラリの依存ライブラリが全て削除される。ということが起る。
今回は express
を v4.15.2
=> v4.15.3
にアップデートする想定で試してみます。
確認環境
- node v8.1.4
- npm v5.0.3
再現
アップデート後のファイル用意
まず事前準備として、アップデート後のファイルを用意します。一応、他のチームメンバーがアップデートしたとか、本番反映するときとかを想定していますが、今回はテストなので適当に別のディレクトリなどで、用意しました。
{
"name": "sample",
"version": "1.0.0",
"description": "",
"private": true,
"license": "ISC",
"dependencies": {
"express": "^4.15.3"
}
}
これと、これでインストールした生成された package-lock.json
を用意しておきます。
アップデート前
アップデート前の package.json
はこちらです。
{
"name": "sample",
"version": "1.0.0",
"description": "",
"private": true,
"license": "ISC",
"dependencies": {
"express": "4.15.2"
}
}
これを npm install
すると、 package-lock.json
が生成されます。これで依存ライブラリを含む express v4.15.2 がインストールされた状態になりました。
$ npm ls | grep express
└─┬ express@4.15.2
実行
ここに先程用意したアップデート後の package.json
と package-lock.json
をチェックアウトするなり、置き換えるなりして持ってきます。diffはこんな感じです。
diff --git a/package-lock.json b/package-lock.json
index b68f31c..9882258 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -34,9 +34,9 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"debug": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz",
- "integrity": "sha1-eYVQkLosTjEVzH2HaUkdWPBJE1E="
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
+ "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4="
},
"depd": {
"version": "1.1.0",
@@ -69,26 +69,14 @@
"integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE="
},
"express": {
- "version": "4.15.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.15.2.tgz",
- "integrity": "sha1-rxB/wUhQRFfy3Kmm8lcdcSm5ezU="
+ "version": "4.15.3",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz",
+ "integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI="
},
"finalhandler": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.3.tgz",
- "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk=",
- "dependencies": {
- "debug": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
- "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4="
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- }
- }
+ "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk="
},
"forwarded": {
"version": "0.1.0",
@@ -146,9 +134,9 @@
"integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0="
},
"ms": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
- "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.1",
@@ -186,14 +174,14 @@
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"send": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/send/-/send-0.15.1.tgz",
- "integrity": "sha1-igI1TCbm9cynAAZfXwzeupDse18="
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.15.3.tgz",
+ "integrity": "sha1-UBP5+ZAj31DRvZiSwZ4979HVMwk="
},
"serve-static": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.1.tgz",
- "integrity": "sha1-dEOpZePO1kes61Y5+ga/TRu+ADk="
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.3.tgz",
+ "integrity": "sha1-n0uhni8wMMVH+K+ZEHg47DjVseI="
},
"setprototypeof": {
"version": "1.0.3",
diff --git a/package.json b/package.json
index 9e0ff27..dae240e 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,6 @@
"private": true,
"license": "ISC",
"dependencies": {
- "express": "4.15.2"
+ "express": "^4.15.3"
}
}
この状態でnpm installすると、
$ npm install
removed 40 packages and updated 4 packages in 1.076s
_人人人人人人人人人人人_
> removed 40 packages <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
$ npm ls
sample@1.0.0
└─┬ express@4.15.3
├── UNMET DEPENDENCY accepts@~1.3.3
├── UNMET DEPENDENCY array-flatten@1.1.1
├── UNMET DEPENDENCY content-disposition@0.5.2
├── UNMET DEPENDENCY content-type@~1.0.2
├── UNMET DEPENDENCY cookie@0.3.1
├── UNMET DEPENDENCY cookie-signature@1.0.6
├── UNMET DEPENDENCY debug@2.6.7
├── UNMET DEPENDENCY depd@~1.1.0
├── UNMET DEPENDENCY encodeurl@~1.0.1
├── UNMET DEPENDENCY escape-html@~1.0.3
├── UNMET DEPENDENCY etag@~1.8.0
....
ということで、依存ライブラリを全部削除してくれます。
あまり詳しく調べてはいないのですが、挙動的にはinstallの際に package-lock.json
を見てインストールする、ライブラリに更新があった場合には依存がなくなっている可能性があるので、不要になったライブラリを探してremoveする。みたいな処理がバグってて、依存関係もろとも全部削除してる。んですかね?
対策
冒頭にも述べましたが、npm v5.2.0ではこの現象が起こらないことを確認しました。v5.1.0からrequireという依存関係の記述が package-lock.json
に追加されたことで修正されたっぽい?
まぁとりあえず、アップデートしましょう。ということで。
終わりに
npm v5.2.0で新しくバンドルされた npx
に気を取られていました。が、気にしないといけないのは目玉機能だけじゃないよ!ということで。
(詳しく調べたら追記するかも?)