.lockファイルって邪魔だよね。って思っている人いたら校舎裏来てください。優しく解説します。
こんにちは! @ykhirao です。最近ジョインさせていただいた案件で composer.lock
のバージョンが本番が一番新しくて、ローカルが一番古い素敵な状況を発見しました
本番環境でSSHして composer update
かけたんだなあーー。そっかーーー、バグ起きたらどないすんねん、。。。。。。
というのが私の感想で、実際にnpmパッケージを使ってバグを再現しながら
ゆっくり解説していこうと思います。どうぞ最後までよろしくお願いします。!!!
このQiitaを呼んで得ること
- あーー、ほんとだ。バグが入る可能性があるんだ!
- lockファイルはちゃんとコミットするね!
というお気持ちになれると思います。
このQiitaで解説しないこと
- 詳しい依存関係の解消法
- packageの公開の仕方
- むずかしいはなし
です!
さて時系列を見てみよう!
こんな事故が起こる可能性がありますよって話をします。
時系列 | OSSのmypackage.js | ローカル | 本番サーバー |
---|---|---|---|
1日目 | v1.0.0公開 | 動いている | 動いている |
2日目 | ローカルでmypackage.jsをinstall 動作確認OK、明後日本番に適応させる |
||
3日目 | v1.0.1公開 バグあり | ||
4日目 | 本番サーバーで新しいコードを反映、install。本番が動かなくなってしまった。ぴえん もちろんソースコードはローカルと同じだし、ローカルで動いていたのになんで…? |
||
5日目 | v1.0.2公開 バグ修正された | ||
6日目 | v1.0.2を適応ローカル確認OK 今度はlockファイルを本番にアップロードする予定! |
||
7日目 | package-lock.jsonを使ってinstallする!今度は動いた! |
npmでパッケージを作りながら説明する
OSSっぽい動作をするpackageフォルダと、ローカル環境と本番環境っぽいフォルダを作る。
yk@yk ~ % cd qiita
yk@yk qiita % mkdir package
yk@yk qiita % mkdir local
yk@yk qiita % mkdir production
yk@yk qiita % ll
total 0
drwxr-xr-x 5 yk staff 160 7 11 00:34 .
drwxr-xr-x+ 83 yk staff 2656 7 11 00:33 ..
drwxr-xr-x 2 yk staff 64 7 11 00:34 local
drwxr-xr-x 2 yk staff 64 7 11 00:34 package
drwxr-xr-x 2 yk staff 64 7 11 00:34 production
yk@yk qiita % cd package
yk@yk package % npm init -y
Wrote to /Users/yk/qiita/package/package.json:
{
"name": "package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
yk@yk package % vim package.json
yk@yk package % vim index.js
yk@yk package % npm publish --access=public
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN package@1.0.0 No description
npm WARN package@1.0.0 No repository field.
up to date in 0.429s
found 0 vulnerabilities
/Users/yk/.nodebrew/node/v13.8.0/lib/node_modules/package -> /Users/yk/qiita/package
yk@yk package % cat index.js
const text = "sample"
module.exports = text;
index.jsにただただ "sample" という文字列を返す動作を記述して、パッケージとして認識させる。
@y_hirao/mypackage
というパッケージをnpmに公開した。
localフォルダでいろいろゴリゴリしてみる。
yk@yk local % npm init -y
Wrote to /Users/yk/qiita/local/package.json:
{
"name": "local",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@y_hirao/mypackage": "^1.0.0"
},
"devDependencies": {},
"description": ""
}
yk@yk local % cat index.js
const text = require("@y_hirao/mypackage");
console.log(text)
yk@yk local % node index.js
sample
sampleという文字列が返却されました。!!!!!!!!!
このときpackage.jsonを見ると ^
キャレット指定なのでバージョンアップは 1.系
は守られるけど残りはすべてアップデートされます。
"dependencies": {
"@y_hirao/mypackage": "^1.0.0"
},
さてパッケージの方を更新します。 v1.0.2
にしましょう!
yk@yk package % cat package.json
{
"name": "@y_hirao/mypackage",
"version": "1.0.2",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
yk@yk package % cat index.js
const text = "sample2"
throw 'エラーを出したい気分';
module.exports = text;
yk@yk package % npm publish
このパッケージをそのまま使うとthrowされます。
さてローカルでinstallしてみましょう!
yk@yk local % npm install
npm WARN local@1.0.0 No description
npm WARN local@1.0.0 No repository field.
audited 1 package in 0.411s
found 0 vulnerabilities
yk@yk
あれ、エラーが起きませんね。
これは 一度ダウンロードしたパッケージはlockファイルというものでバージョン指定されているので、新しく勝手にバージョンがあがったりしないのです。
さてローカルから本番環境に package.json と index.js をコピーしてnpm installして動かしてみましょう!
yk@yk production % cp ../local/package.json package.json
yk@yk production % cp ../local/index.js index.js
yk@yk production % npm i
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN local@1.0.0 No description
npm WARN local@1.0.0 No repository field.
added 1 package and audited 1 package in 2.811s
found 0 vulnerabilities
yk@yk production % node index.js
/Users/yk/qiita/production/node_modules/@y_hirao/mypackage/index.js:2
throw 'エラーを出したい気分';
^
エラーを出したい気分
(Use `node --trace-uncaught ...` to show where the exception was thrown)
さて、、、本番環境でinstallを走らせるとエラーがおきました。。。。
npm install
したときに package-lock.json
がないと package.json
を使って ^1.0.0
が指定されているので 1.系で一番新しいもの
つまり今回だとバグが混入している v1.0.2
がインストールされたことになります。
lockファイルを見てみましょう。
yk@yk production % cat package-lock.json
{
"name": "local",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@y_hirao/mypackage": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@y_hirao/mypackage/-/mypackage-1.0.2.tgz",
"integrity": "sha512-W2RoQsC1FVnHxximVJMovEvfl/3WNI95EjGxPbMlmyuDZ+0SImS76dOII/0AiP4cVVjXZUbFzaLs9h6l8TrrFQ=="
}
}
}
まさしく v1.0.2
が指定されていますね!localだともちろん最初に npm install
したときに最新だった @y_hirao/mypackage
の v1.0.0
が使われています。
yk@yk local % cat package-lock.json
{
"name": "local",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@y_hirao/mypackage": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@y_hirao/mypackage/-/mypackage-1.0.0.tgz",
"integrity": "sha512-auQ5grIpWd0IRkMR3rn6xRjIhGZqBu/Q/g1lDkS5AWakAysrZ3iQAIRngbgBGBAFlPZxQ/LCVYdAW+3VLxeSEw=="
}
}
}
更にインストールされているフォルダを確認しても
yk@yk production % cat node_modules/@y_hirao/mypackage/index.js
const text = "sample2"
throw 'エラーを出したい気分';
module.exports = text;
yk@yk production %
どう見てもエラーが起きそうです。
package-lock.jsonをlocalからコピーしてきましょう。
yk@yk production % cp ../local/package-lock.json package-lock.json
yk@yk production % npm i
npm WARN local@1.0.0 No description
npm WARN local@1.0.0 No repository field.
updated 1 package and audited 1 package in 0.45s
found 0 vulnerabilities
yk@yk production % cat node_modules/@y_hirao/mypackage/index.js
const text = "sample"
module.exports = text;
yk@yk production % node index.js
sample
yk@yk production %
lockファイルを持ってきてインストールするだけで、エラーが起きなくなりました!
まとめ
本番環境で lockファイルごと更新する composer update
とかlockファイルの存在しない状態での npm install
とか、そんなことはやめましょう。ってことを主張したいです!!!!!
ローカルでしっかり確認してlockファイルを作り、それを本番にアップロードして、lockファイルの状態で依存パッケージをインストールしちゃってください。。
インストールする時期によって最新のバージョンが使われるので、もしそのバージョンにバグがあるのなら本番死んじゃいますよ。。
終わりに
新しい会社に入って色々根本的に変えたいところがあるので、最近はdevopsの領域をごりごり触らせていただいてます。環境構築、開発フローの策定とかもろもろやらせてもらっているのでかなり楽しいです
読んでいただきありがとうございました。lockファイル入門したい方、事故りそうな不安があるかたは同僚と一緒に「弊社のパッケージ依存関係の運用どうする…?」と一度話し合ってみてください。
ありがとうございました。
.