※スマホ対応はしてません。

カテゴリー: JavaScript

`package-lock.json` はNPMリポジトリーに含まれないよ(NPMおれおれAdvent Calendar 2019 – 07日目)

カテゴリー: JavaScript

HERSHY'SのAdvent Calendar(本物)の7日目を開けたところ。
NPMおれおれAdvent Calendar 2019 – 07日目

そういう仕様です。

先にまとめ

  • package-lock.json は NPM リポジトリーに追加されない
  • つまり依存パッケージとしてインストールされる場合、バージョンは固定されない
  • Git のリポジトリーには含めてください

公開されない

One key detail about package-lock.json is that it cannot be published, and it will be ignored if found in any place other than the toplevel package. It shares a format with npm-shrinkwrap.json, which is essentially the same file, but allows publication.

package-lock.json の鍵となる特徴として、公開されないという点があります。またトップレベルパッケージ以外の場所のものは無視されます。npm-shrinkwrap.json は本質的に同じファイルでありその書式を共有していますが、こちらは公開が可能です。

ここでいう「公開 (publish) 」とは npm-publish のことで、NPM パッケージとして公開するという意味です。公開すると npm install xxx でインストールできるようになります。

というわけで npm install xxx でインストールしたパッケージには package-lock.json は含まれていません。

パッケージとしてはバージョンが固定されない

package-lock.json を利用することで利用中の依存パッケージのバージョンをツリー全体で記録できるのですが、前述のとおり NPM のリポジトリーには登録されないので、インストールされるのは package.json に記載のバージョンが許容する範囲の最新のもの、になります。

つまり、手元で開発する場合にのみ package-lock.json が意味を成すって感じですね。

だからといって使わなくてもいいじゃんみたいな話じゃないです。それは別の日に。

shrinkwrap

npm-shrinkwrap.json は package-lock.json と同じようなものですが、こちらは NPM リポジトリーへ含めることが可能です。

可能ですが、強く非推奨 (strongly discouraged) とされています。

おしまい

偉そうな顔して shrinkwrap 使ったことないので正直肌感がわかってないです。

参照

関連

プロジェクトのクリーンインストールとテストを同時に行うやつ(NPMおれおれAdvent Calendar 2019 – 06日目)

カテゴリー: JavaScript

HERSHY'SのAdvent Calendar(本物)の6日目を開けたところ。
NPMおれおれAdvent Calendar 2019 – 06日目

npm install-ci-test というのがあるのに気付きました。ci と test をまとめてやってくれるとのこと。

This command runs an npm ci followed immediately by an npm test.

翻訳もいらないくらい簡潔な説明だ。これしか載ってない。

あとショートカットとして、npm cit というまさに ci + test という感じのがあります。

クリーンインストールって

npm ci でやるやつです。一度 node_modules を空にして、package-lock.json を元に再構築します。

使いどころ

CI では ci と test とどうせやってると思うんだけど、その 2 行を 1 行にまとめることができますね。フルスペルなら可読性も問題ないかな。

あとはやっぱ git clone 直後にこれ走らせると良いんじゃないでしょうか。しらんけど。

おしまい

見つけたばっかでまだ使ったことないです。

参考

関連

`package-lock.json` のひみつ(NPMおれおれAdvent Calendar 2019 – 05日目)

カテゴリー: JavaScript

HERSHY'SのAdvent Calendar(本物)の5日目を開けたところ。
NPMおれおれAdvent Calendar 2019 – 05日目

言うほど秘密ってもんでもないですが。

なにそれ

package-lock.json は npm install なんかをすると生成されるファイルで、インストールされているパッケージのツリーを表します。このファイルと npm ci を利用して全く同じツリーを再構築することが可能になります。

困ったちゃん

このファイル自体は便利なものだと思うんですが、困った点がひとつ。「ロック」とう名前に反して何もロックしない点です。

ロックファイルがある状態で npm install すると、そのロックされたバージョンのパッケージ群がインストールされる、というのを期待するんですが、実際はそんなことなく、新しいものがあればそちらをインストールし、逆にロックファイルを更新します。ロックとは。

昔はロックしていた

大昔はこの package-lock.json はなく、package.json だけでした。でも package.json だとバージョンに幅を持たせた指定ができて、それはそれで便利だけどバージョンをロックもしたいよねってんでロックファイルを導入されます。

すると package.json の更新をしても実際のパッケージが更新されなくて困った、という問題があったようです。そりゃあロックしてるからな。

どうすんの

npm install の代わりに npm ci を利用してください。こちらであればロックファイルに記載のバージョンを利用してインストールが行われます。

ただし互換機能ではないので、違いには気を付けてください。こちらをどうぞ。

FAQ

package-lock.json ってなに

node_modules がどうなってるかっていう記録です。

package.json と何が違うの?

package.json はプロジェクトにまつわる諸々を載せるもので、よく自分で編集します。依存パッケージのバージョンも記載されますが、例えば "^1.0.0" のように幅のあるバージョンを指定することができます。

package-lock.json は npm が自動出力するもので、パッケージの依存関係がツリー状に保存されます。バージョンは node_modules に実際に置かれているものが記載されます。

Git リポジトリーで管理すべき?

はい。

CI で利用できるし、何か問題があったときに巻き戻すのにも使えます。

なんか git clone からの npm install で変更されちゃったんですけど?

そういうもんです。以下の選択肢があります。

  • 変更を戻してから、代わりに npm ci を利用して、プロジェクトとして現在採用されているバージョンのパッケージ群をインストールする
  • 変更を戻さずに、そのままコミットして利用バージョンを更新する

なんで npm install でロックファイルが変わるの?

package.json におけるパッケージのバージョンに幅がある場合、インストール時点で指定範囲に収まるうち最新のものがインストールされます。そのため過去の実行時よりも新しいバージョンが出ているならそちらがインストールされ、またそれに合わせてこのロックファイルが更新されてしまいます。

まあロックっていう名前が良くないよね。

編集していい?

だめ

Git でコンフリクトした

package-lock.json を削除して npm install すればちゃんとした状態でまるっと復活します。

package.json 無事でないならさきにそっちを解消してから、同じ手順です。

まとめ

  • npm install は node_modules から package-lock.json を生成する
  • npm ci は package-lock.json から node_modules を構築する

おしまい

なんか違ってたらごめん。

参考

履歴

  • 2019-12-08
    • npm ci に関する記述をもっと追加
  • 2019-12-05
    • 公開

`npm install` の代わりに `npm ci` が使えるかも(NPMおれおれAdvent Calendar 2019 – 04日目)

カテゴリー: JavaScript

HERSHY'SのAdvent Calendar(本物)の4日目を開けたところ。
NPMおれおれAdvent Calendar 2019 – 04日目

先にまとめ

  • npm ci は npm install と同じように、全依存パッケージをインストールする
  • npm install は package-lock.json を更新することがある
  • npm ci は package-lock.json を更新しない
  • npm ci は node_modules を削除してからインストールする

npm ci ってなんだ

npm install に似ているが、CI のような自動化された環境での利用が想定されているもの。あるいは開発環境でクリーンインストールするのにも使える。処理はいくつかの機能を省略するので、npm install より圧倒的に高速な場合がある。

ドキュメントを読むとそんな感じらしい。

基本的には CI で回す場合はこちらを使いましょう、という理解で良さそう。CI ってなに?くらいの段階の方は別に npm install だけでも大きな問題はないはず。

npm install との違い

  • package-lock.json or npm-shrinkwrap.json が必須。ないとコケる
  • それらが package.json の記述と矛盾する場合、コケる
  • 依存追加には使えない。(npm install xxx でやる)
  • node_modules はいったん全消しされる
  • package-lock.json を更新しない

npm install の問題点

npm install は package-lock.json を更新することがしばしばあります。

理由は package.json に記述する semver が幅のあるバージョンを許すためで、また package-lock.json は(”lock” という名前に反して)node_modules の実際を反映するものだからです。本当にロックしちゃうとそれはそれで問題があったため変更されたようで。マジかよ。

逆に npm ci は package-lock.json を元に node_modules を構築します。

npm ci の使いどころ

  • CI で回す場合
  • git clone 直後
  • 何かがおかしいので node_modules を空にしてやり直すとき
  • 過去の状態を復元するとき

インストールスクリプト

ちょっと仕組みがよくわかんないんだけど、npm ci したら以下のスクリプトは自動で実行されました。npm install 扱いなんですね。

  • preinstall
  • install
  • postinstall

ソース ちらっと見てみたけどなんもわからん。

おしまい

というわけで、CI では npm ci を使うと良さそうです。

package-lock.json については後日また改めて。

参考

NPMスクリプトに `npx` や `node_modules/.bin` は書かなくて良い(NPMおれおれAdvent Calendar 2019 – 03日目)

カテゴリー: JavaScript

HERSHY'SのAdvent Calendar(本物)の3日目を開けたところ。
NPMおれおれAdvent Calendar 2019 – 03日目

パスは自動で追加されるので、気にせずそのまま実行ファイル名を指定してしまって大丈夫。

例えばこれ↓だけで node_modules/.bin/tsc が(あれば)実行されます。

{
  "scripts": {
    "build": "tsc"
  }
}

同様に npx も書く必要なし。プロジェクトの外、グローバルにインストールされたものを呼び出すってなら必要だけど、ローカルにインストールするべきですよ。

ドキュメントの記載

In addition to the shell’s pre-existing PATH, npm run adds node_modules/.bin to the PATH provided to scripts. Any binaries provided by locally-installed dependencies can be used without the node_modules/.bin prefix.

シェル既存の PATH に加えて、npm run は node_modules/.bin を PATH へ追加してスクリプトへ提供します。ローカルインストールされた依存のバイナリーは、node_modules/.bin 接頭辞なしで利用可能です。

だそうです。