🚄

$npm ci $npm install $npm audit fix $npm start【既存Expressプロジェクト参画を例に】

2023/09/16に公開
  • 既存Expressプロジェクトへの参画を例にして、npmの使い方をメモしておこうと思います。今回説明するのは以下です。
$ npm ci
$ npm install
$ npm audit fix
$ npm audit
$ npm fund
$ npm start

※脱線してるので急いでる時は①②③④のところだけ実行すれば良い

前提情報

$ npm -v
9.6.7

① リポジトリをクローン

$ git clone [リポジトリパス]

② パッケージをインストール

  • 依存関係の解決のためにインストールされるパッケージも含めてバージョンを揃える必要がある場合は$ npm ci
  • そこまで揃える必要はない場合は$ npm installを実行します。
  • $ npm ciはpackage-lock.jsonを元にパッケージがインストールされます。
  • $ npm installはpackage.jsonを元にパッケージがインストールされます。

package-lock.json

  • package-lock.jsonでは、依存関係の解決のためにインストールされたパッケージ分も含めて全て管理されています。
  • つまり、$ npm ciによって、package-lock.jsonを元にインストールすると依存関係の解決のためにインストールされるパッケージに関してもバージョンをcloneしてきたプロジェクトと揃えることができます。
    https://docs.npmjs.com/cli/v10/commands/npm-ci?v=true

package.json

  • 対して、package.jsonのdependenciesとdevDependenciesを見ればわかるように、依存関係の解決のためにインストールされるパッケージ分までは厳密にバージョン管理されていません。
  • つまり$ npm installによって、package.jsonを元にインストールすると依存関係の解決のためにインストールされるパッケージに関してはバージョン指定をしていないため、最新バージョンのものがインストールされてしまいます。
    具体としては、あとからプロジェクトに入った人ほどと依存関係の解決のためにインストールされるパッケージのバージョンが新しくなるので、プロジェクト内で徐々にずれが生じていきます。

$ npm install

  • package.jsonのdependenciesとdevDependenciesいうセクションに記載されているパッケージがnode_modulesディレクトリにインストールされていきます。
  • dependenciesとdevDependenciesにはこのプロジェクトを開発するのに必要なパッケージの情報が登録されています。
  • dependenceは依存という意味で、このプロジェクトがこれらのパッケージに依存している、ということです。

$ npm audit fix

  • $ npm installしたときに、package-lock.jsonが古いもので、versionが古かったりすると、以下の通り脆弱性と判断されることがあります。
The package-lock.json file was created with an old version of npm, so supplemental metadata must be fetched from the registry.
This is a one-time fix-up, please be patient...
added 65 packages, and audited 66 packages in 1s
5 vulnerabilities (4 high, 1 critical)

To address all issues, run:
  npm audit fix
Run `npm audit` for details.

package-lock.json ファイルは古いバージョンの npm で作成されているため、補足的なメタデータをレジストリから取得する必要があります。
これは一度限りの修正なので、しばらくお待ちください...。
65 個のパッケージを追加し、1 秒で 66 個のパッケージを監査した。
5 件の脆弱性 (4 件が高難易度、1 件がクリティカル)
すべての問題に対処するには
npm audit fix
詳細は npm audit を実行してください。

  • そういう時は記載されている通り$ npm audit fixを実行しましょう。詳細を知りたい場合は$ npm auditを実行しましょう。
    するとパッケージのインストールが成功し以下のような表示がされます。
added 10 packages, removed 1 package, changed 48 packages, and audited 75 packages in 949ms

10 packages are looking for funding
  run `npm fund` for details
found 0 vulnerabilities

949ms で 10 パッケージを追加、1 パッケージを削除、48 パッケージを変更、75 パッケージを監査。
10 個のパッケージが資金を探している
詳細は npm fund を実行してください。
0 件の脆弱性を発見

  • fundは資金という意味なので資金提供を呼び掛けられています。

devDependencies

  • 開発するためにcloneしてきた「パッケージhoge」のpackage.jsonのdevDependenciesセクションにeslintが指定されているとします。
  • パッケージとは、package.jsonファイルで管理しているファイルかディレクトリのことです。
package.json
 "devDependencies": {
    "eslint": "^8.49.0"
  }

https://zenn.dev/y__adler/articles/94f3f04c667a82

  • $ npm installすればpackage.jsonに記載されているパッケージは全てinstallされるのでeslintも当然インストールされます。これはcloneしてきた「パッケージhoge」の中で$npm installを実行するのは開発者だから開発に必要なパッケージも、オプションなしでインストールされるのです。

  • 一方で、この「パッケージhoge」をパッケージとして公開したとします。
    その場合パッケージhogeの開発者ではなく「利用者」が利用者のプロジェクトの中で$npm install パッケージhogeを実行します。その場合は、devDependenciesセクションのパッケージはインストールされません。
    なぜなら、利用者はパッケージhogeの開発者ではないのでパッケージhoge用の開発用パッケージなんて要らないからです。

$ npm install --production

By default, npm install will install all modules listed as dependencies in package.json.
With the --production flag (or when the NODE_ENV environment variable is set to production), npm will not install modules listed in devDependencies.

  • $ npm installはpackage.jsonに記載されているパッケージ全てinstallされます。

  • 対して、$ npm install --productionの場合、devDependenciesにある開発用パッケージはinstallされません。

  • そのため、開発用のパッケージをインストールする必要がない時は--productionオプションを付けましょう。

https://docs.npmjs.com/cli/v10/commands/npm-install

③node_modulesの確認

  • パッケージのインストールが完了すると、node_modulesというディレクトリが新たに作成されています。
  • 展開すると、プロジェクトを動かすのに必要なパッケージがダウンロードされ、こちらに格納されていることがわかります。

④サーバ起動

  • プロジェクトを動かすのに必要なパッケージのインストールが完了し、これで動かす準備が整いました。
    (.envファイルとかは省略)
$ npm start

終わり

scripts

  • package.jsonのscriptsセクションでは以下のようにプロジェクト専用コマンドを定義できます。
package.json
"scripts": {
    "hoge": "実行内容の実体"
  },
対象プロジェクトのターミナル
$ npm run hoge
  • 具体としては、以下の場合はstartというコマンドにnode server.jsが割り当てられています。
package.json
  "scripts": {
    "start": "node server.js"
  },
  • なのでこの場合は$ npm run start、またはこのstartは予約後なので、runを省略して$ npm startで実行することができます。

  • 実態としては $ node server.jsなのでnodeコマンドでserver.jsというファイルを実行することで、サーバアプリケーションを動かしていることがわかります。

Discussion