はじめに
JavaScriptでライブラリをインストールしたいと思った時に、npm
コマンドを使おうと思ったのですが、ライブラリの公式ドキュメントをみるとnpx
コマンドを使っているケースをよく見かけます。
npxってなんだ?npmと何が違うの?
ってなったので調べてみようと思います。
前提知識
Node.js
そもそもNode.js
って知らない間に使用しているケースが多いですよね。
Node.js
はパソコン上で、JavaScriptのプログラムを実行するためのJavaScriptの実行環境です。
元々、JavaScriptはブラウザ上のみで動作することを想定して作られた言語で、ブラウザ上でしかJavaScriptのプログラムを実行することができませんでした。
これはどういうことかというと、PythonやGoといったような言語はパソコン上で使用することが可能で、OSの機能にアクセスしてファイル操作等が可能でした。
JavaScritptは、ブラウザ上で動作する言語のため、ブラウザ(Webアプリケーション)からOSの操作を行うというのはセキュリティ上問題があるので、パソコン上で動かせなかったということです。
OSの操作の全てができないだけで、カメラ等の限定的な機能は使えます
パッケージ
package.json
で管理しているプロジェクトを言います。
パッケージという名前ですが、概念的にはライブラリ
やフレームワーク
と同じです。
packcage.json
プロジェクトで使用するパッケージの依存関係を記述しています。
ここに記述されたものをnpm install
でインストールしたりします。
package-lock.json
インストールされたパッケージを記述しています。
package.jsonは、インストールすべきパッケージを記述
package-lock.jsonは、結果的にインストールされたパッケージを記述しています。
node_modules
npm install
コマンドを使ってインストールされたパッケージが集められるディレクトリのことです。
じゃあnpmとnpxって何?
前提知識を入れたところで、npmとnpxの違いについて説明しようと思います。
npm(Node Package Manager)
Node.jsを入れると自動的にインストールされるパッケージマネージャーのことを指します。
npmを使うことで依存関係や競合関係を解決してくれます。
npx(Node Package Executor)
npxはパッケージの実行ツールです。
インストールされていないパッケージを探してインストールして、インストールを完了したらそのパッケージを削除してくれます。
例えば、npmではインストールされたパッケージやpackge.jsonに記述されたパッケージを動かす際に
npm run
を行うのですが、その内部で動いているツールです。
なぜインストールにnpxを使っているところがあったりするのか
先述したようにnpxは一時的にインストールして、使い終わったら削除します。
例えば、Next.jsのプロジェクトでshad/cn
等のUIコンポーネントライブラリを使いたいとしましょう。
shad/cnのパッケージはコンポーネントを記述するようになっているので
npx shadcn@latest add button
とコマンドを打った場合、これはbuttonコンポーネントの追加パッケージを実行しています。
この追加パッケージは一度しか使う必要がないので、npxを使ってパッケージを実行したら削除しています。
仮にnpmを使用した場合は、一度しか入れる必要がないbuttonコンポーネントを入れるようのパッケージをnode_modules
に対して、ずっと入れることになってしまい、容量を圧迫してしまいます。
一度しか使う必要がないパッケージは、npxを使ってパッケージを実行したら削除することで、環境を汚さずに使用するというメリットがあります。
なので、ReactやNextのプロジェクトを立ち上げるときも立ち上げる時に使用するパッケージは一度実行するだけなので
npx create-react-app my-app
npx create-next-app@latest
って打ちますよね。
また、npxで一時的にパッケージをインストールすることから、最新バージョンのパッケージを使えるという利点があります。
npmとnpxでのインストールの違い
上記を踏まえてnpmとnpxの使い方の違いとしては
- npm: プロジェクトを動かすために入れるパッケージをインストールするとき
- npx: 一度実行したらいらなくなるパッケージを使いたいとき
となります。
このようにケース毎にnpmとnpxを使い分けています。
yarnとpnpmについて
npmとまた違うパッケージマネージャーとしてyarnとpnpmがあります。
自分もインターン等でyarnとpnpmを使ったことがありますが、違いがわからないませんでした。
今回npmを調べるということでついでに調べてみました。
yarn
Facebookが作成したパッケージマネージャーです。
npmと互換性があるので、同じPackageManager
を使ってインストールすることができます。
yarnは、ダウンロードされたパッケージはキャッシュするので、インストール速度が早いという特徴があります。
数年前まではyarnのほうがnpmよりパッケージのインストール速度が早かったらしく、それで人気が出たそうです。
現在はnpmもそこまで速度に差が無いと言われているので、もはや好みなのかなと思っています。
Yarn はコード実行前に、インストールされた各パッケージの整合性をチェックサムで検証するので、セキュリティ面で高いという特徴もあります。
yarnの特徴
- インストールが若干npmより早い
- セキュリティ面が高い
pnpm
Performant NPMの略称で、こちらもnpmやyarnと同じパッケージマネージャーです。
ただこちらはnpmと比べると違いがいろいろあります。
1.ストレージの効率
npmやyarnは、プロジェクト毎にパッケージをインストールしていたため、複数のプロジェクトにそれぞれ同じパッケージが入っているということが起きていました。
pnpmでは、そのパッケージを一箇所に集め、それに対するリンクを使用することでストレージを節約しています。
2.インストールが高速
JavaScriptのパッケージマネージャーでは、インストールする際に、Resolving
、Fetching
、Linking
を行っていました。
それぞれ
-
Resolving
:依存関係の解決 -
Fetching
:ディレクトリ構造の計算 -
Linking
:依存関係をリンク
を行っています。
従来は、以下の画像のように、複数パッケージをインストールするとなったら。全てのパッケージがResolving->Fetching、Fetching->Linkingと段階移行を確定させていないと実行できませんでした。
pnpmでは、下画像のようにそれぞれのパッケージが各ステージを進めるようになったことで、インストールが高速化しました。
3.packcage.jsonが厳格化
npm等では、一つのパッケージを動かすために必要なパッケージをインストールしていました。
pnpmでは、先述したようにリンクを使用してパッケージを使用します。
そのリンクひとつだけをpackage.jsonを記述することで、動かすためだけに必要なパッケージをpackage.jsonに記述する必要がなくなり、必要なパッケージのリンクだけをpackage.jsonに書くようになっています。
これで意図しないパッケージの動作を制限できます。
pnpmの利点
- パッケージがディスクを圧迫しない
- インストールが早い
- 依存関係が厳格
最後に
ライブラリ毎にnpmやnpx異なると思いますが、npmとnpxの特性を理解しておくとそのライブラリについての知識が深まっていいと思います。
また、nodeのパッケージマネージャーはどれもいいものなので、周りの経験値や要件に合わせて使用したらいいと感じました。
個人的にはpnpmいいなと思っています