- npm は、大規模なパッケージ レジストリとしてだけでなく、Node.js の依存関係をインストール、更新、削除、監査するための主要な CLI ツールとしても機能します。
- プロジェクトは、main、exports、imports、type などのフィールドを介して依存関係、スクリプト、エントリ ポイントを定義するために package.json に依存します。
- ローカルインストールとグローバルインストール、semver 範囲、依存関係の種類 (dependencies、devDependencies、optionalDependencies) によって、パッケージの使用方法と場所が制御されます。
- 高度なエクスポート、条件付きエクスポート、サブパスのインポートにより、nodebbs などのパッケージがさまざまな環境に公開する内容をきめ細かく制御できます。
もしあなたが、 「nodebbs」のようなnpmパッケージ Node.jsエコシステムに適合するには、まず npmとは何かパッケージの構造、Node.jsがモジュールを解決・公開する方法など、npmは様々な要素から構成されています。近年のNode.jsプロジェクトは、コードのインストールだけでなく、スクリプト、セキュリティ、バージョン管理、そしてパッケージが他のユーザーによってどのように利用されるかといった管理においても、npmに大きく依存しています。
このガイドでは、 npmをゼロから — それが何であるか、ローカルパッケージとグローバルパッケージがどのように機能するか、それらをどのようにインストール、更新、削除するか、 package.json 構造化されており、高度な機能のような exports および imports フィールドは、パッケージ(例えばnodebbsのようなフォーラムエンジン)がユーザーに提供するものを制御します。すべてが分かりやすい英語で豊富な例とともに説明されているので、npmパッケージを自信を持って公開し、使用できます。
npmとは何か、そしてnodebbsのようなパッケージにとってなぜ重要なのか
npm (ノードパッケージマネージャー) はコマンドラインツールであると同時に、オープンソースのNode.jsパッケージの巨大なオンラインレジストリでもあります。Node.jsをシステムにインストールすると、npmも自動的にインストールされ、コミュニティによって公開されている数百万もの再利用可能なモジュールにすぐにアクセスできるようになります。 npmjs.com.
当学校区の npmレジストリ は事実上、世界最大の単一言語コードリポジトリであり、100万を超える公開パッケージが、ほぼあらゆるタスクをカバーしています。これらのパッケージは、小さなユーティリティ(単一の関数)から、日々の運用アプリを支える完全なフレームワーク、CLI、アプリケーションスケルトンまで、多岐にわたります。
もともと、 npmは設計されました バックエンドのNode.jsプロジェクトの依存関係管理のみを目的としていましたが、現在ではフロントエンドワークフローの中核ツールにもなっています。React、WebpackやViteなどのツール、CSSフレームワーク、テストランナーなど、多くのツールをインストールでき、すべてnpmパッケージとして配布されています。
特定のパッケージを扱う場合、例えば nodebbs, npmはコードのダウンロードを担当します依存関係を解決し、チーム全体でバージョンの一貫性を保ち、公開するスクリプトやCLIを配線します。そのため、パッケージを自分で評価、カスタマイズ、さらには公開したい場合は、npmの理解が不可欠です。 広範囲にわたるnpmサプライチェーン攻撃.
Node.js、npm、そしてそれらのインストール方法
nodebbsを含むnpmパッケージを使用するには、 Node.jsとnpmがインストールされている マシン上で。npm は Node にバンドルされているため、公式サイトから Node をインストールするだけで準備完了です。
推奨される方法は、次のようなバージョンマネージャを使用してNode.jsをインストールすることです。 nvmを使用すると、複数のNode.jsバージョンとnpmバージョンを切り替えることができます。これにより、異なるNode.jsバージョンでプロジェクトを簡単にテストできるようになり、システム全体に適用するインストーラーで発生する可能性のある権限の問題を回避できます。
すぐに確認することができます Nodeとnpmはすでに存在しています ターミナルを開いて以下を実行します: node -v Nodeのバージョンを確認し、 npm -v npmのバージョンを確認します。
Node.jsが見つからない場合、またはバージョンが古すぎる場合は、 長期サポート(LTS)リリース from nodejs.org お使いのオペレーティングシステムに応じて異なります。WindowsとmacOSではインストーラーが全てを設定します。LinuxではNodeSourceまたはディストリビューションの推奨方法、あるいは次のようなバージョンマネージャーを使用することができます。 nvm.
npm のコア概念: パッケージ、モジュール、レジストリ
Node.jsの世界では、 "パッケージ" モジュールやアプリケーションに必要なすべてのもの(JavaScriptファイル、メタデータ、ドキュメント、そして場合によってはビルドアーティファクト)が含まれた、バンドルされたコードです。パッケージは通常、 package.json 何が含まれているかを説明するファイル。
A 「モジュール」 Node.jsでインポートできるコード単位です。 require() or importnpm パッケージは通常、利用者が使用できるように1つ以上のモジュールを公開します。例えば、ユーティリティライブラリは単一のメインモジュールをエクスポートする一方、nodebbs のような複雑なパッケージは、サーバー部分とクライアント部分の複数のエントリポイントを公開する場合があります。
パッケージは公開されます npmレジストリ (またはプライベートレジストリに)保存することで、他の開発者が簡単なコマンドでインストールできるようになります。npmは内部的にファイルをダウンロードし、依存関係ツリーを検証し、すべてを node_modules フォルダーに保存して、アプリでインポートできるようにします。
npmパッケージの一般的な例としては、次のようなフレームワークがあります。 Express、React、Vue、LodashやChalkなどのユーティリティ、MongooseやSocket.ioなどのバックエンドヘルパー、Jest、Webpack、Babel、Nodemon、Axiosなどのツールなどがあります。nodebbsのようなパッケージは、これらに加えて、アプリケーションスタックにプラグインできるインストール可能な依存関係として存在します。
コマンドラインでnpmを操作する
当学校区の npm コマンドラインインターフェース (CLI) パッケージのインストール、削除、更新、検査、そしてプロジェクトスクリプトの実行方法です。Windowsでは通常、コマンドプロンプトまたはPowerShellを開きます。macOSとLinuxではターミナルを使用します。
最もよく使われるnpmコマンドのいくつかは次のとおりです。 npm install, npm uninstall, npm update, npm init, npm start, npm test, npm publishこれらのコマンドを組み合わせることで、Node.js プロジェクトの依存関係とライフサイクル タスクを管理するために必要なほぼすべてがカバーされます。
プロジェクトに新しいパッケージをローカルにインストールするには、通常、 npm install <package-name> プロジェクトルートから。これによりパッケージがダウンロードされます node_modules そして、現代のnpmでは、自動的にエントリを追加します dependencies in package.json.
グローバルインストール、使用 npm install -g <package-name>は、システム上のどこでも利用できるようにしたいツールのために予約されています。 nodemon, typescript、またはその他のCLIで使用できます。アプリレベルのライブラリ(nodebbsを含む)は、ほとんどの場合、ローカル dependencies を代わりにお使いください。
Nodeプロジェクトの初期化とpackage.jsonの役割
すべての本格的なNode.jsプロジェクトは、 package.json アプリまたはライブラリのマニフェストとして機能するファイルです。メタデータ(名前、バージョン、説明)、スクリプト、依存関係、パッケージの読み込み方法に関する情報が格納されます。
このファイルを作成するには、 npm init 空のフォルダにプロジェクトに関するいくつかの質問に答えてください。質問をスキップしたい場合は、 npm init -y 最小限の package.json 後で編集できる適切なデフォルト設定。
Once package.json 存在する場合、インストールするすべてのパッケージは、 dependencies, devDependencies、または他の専用セクション。これにより、他の開発者がリポジトリをクローンして、 npm install 完全な依存関係ツリーを復元します。
公開したいnodebbsのようなパッケージの場合、 package.json パッケージ名、エントリポイント、次のようなフィールドも宣言します。 main, exportsまたは type Nodeがモジュールを解決する方法を制御する。 package.json npm パッケージの使用と生成の両方に中心的な役割を果たします。
npm パッケージのローカルインストールとグローバルインストール
ローカルパッケージは現在のプロジェクトの node_modules ディレクトリ内でのみ利用可能であり、そのプロジェクト内でのみ利用可能です。 npm install express or npm install nodebbs プロジェクト フォルダーでは、パッケージはそのアプリの依存関係グラフの一部になります。
このローカルインストール戦略は、 プロジェクト間のバージョン競合 各プロジェクトが依存関係のコピーを独自に保持しているためです。あるアプリがExpress 4を使用し、別のアプリがExpress 5を使用しても、互いに干渉することはありません。
グローバルパッケージは、 npm install -gはシステム全体の場所に配置され、通常はコマンドラインツールを公開します。これは次のような場合に使用できます。 nodemon, typescript、またはグローバル プロジェクト ジェネレーター用ですが、nodebbs のようなアプリケーション コードをグローバルにすることはほとんど望ましくありません。
npmでは、グローバルインストールプレフィックスを変更することもできます。 npm config set prefix <path>これは、管理者権限がない場合や、グローバルCLIのインストール時に権限エラーを回避したい場合に便利です。これにより、グローバルツールはユーザーが書き込み可能なディレクトリに保存されます。
依存関係の管理: インストール、更新、削除
日々の仕事では、多くの時間を費やします npm の依存関係を追加、更新、そして時々削除するnpm は、ローカルとグローバルの両方で、これらの各操作に対して簡単なコマンドを提供します。
既存のプロジェクトにすべての依存関係をインストールするのは、実行するだけです。 npm install ディレクトリ内で package.json npmは依存関係とdevDependenciesのリストを読み取り、 node_modules それに応じてフォルダーを作成します。
単一の依存関係を追加するには、 npm install <package-name> (または npm i <package-name> (略して)オプションで以下のようなフラグを付けることができます --save-dev, --save-optionalまたは --no-saveこれらのフラグは、パッケージが通常の依存関係として記録されるか、開発専用の依存関係として記録されるか、まったく記録されないかを制御します。
依存関係の更新はプロジェクト全体で実行できます。 npm updateは、パッケージを、以下のバージョン範囲を満たす新しいバージョンにアップグレードします。 package.json単一のパッケージをターゲットにすることもできます。 npm update <package-name>、または追加 -g グローバル ツールを更新する場合。
パッケージのアンインストールは対称的です。 npm uninstall <package-name> 削除します node_modules そしてクリーンアップ package.json エントリー。使用 npm uninstall -g グローバルにインストールされたパッケージに対しても同様の処理が行われます。
依存関係、devDependencies、optionalDependenciesを理解する
In package.jsonnpmは、依存関係がいつどのように必要になるかに応じて、異なる種類の依存関係を区別します。この分離を適切に行うことで、プロダクションバンドルをスリム化し、ツールの柔軟性を維持できます。
dependencies アプリケーションを本番環境で実行するために必要なパッケージをリストします。Webアプリの場合、Express、Mongoose、あるいはサーバースタックの一部として組み込む場合はnodebbs自体が含まれる場合があります。
devDependencies Jest、ESLint、Webpack、Babel、Nodemonなど、開発時やビルド時にのみ必要なパッケージが格納されます。これらは実行時にはインストールされません。 npm install --productionこれにより、本番環境が軽量化されます。
optionalDependencies アプリの機能を強化するものの、厳密には必須ではないパッケージが含まれています。オプションの依存関係のインストールに失敗しても、npm はそれを致命的なエラーとして扱いません。コードでその依存関係が存在しないことを適切に処理することが期待されます。
旗など --save-prod (デフォルト)、 --save-dev (または -D)、及び --save-optional 新しくインストールされたパッケージがどこに記録されるかを制御する。歴史的には、明示的な --save フラグですが、現代のnpmは npm install <name> デフォルトでは依存関係に保存操作として実行されます。
Semverと特定のパッケージバージョンのインストール
npmは セマンティックバージョニング(semver) パッケージのバージョン管理は、複雑なライブラリや、時間の経過とともに進化する可能性のあるnodebbsのようなパッケージに依存している場合に重要です。Semverはパターンを使用します。 MAJOR.MINOR.PATCH (例えば、 1.4.3).
セムバーでは、 メジャー番号 重大な変更があった場合は増分します。 マイナー 下位互換性のある機能の追加、および PATCH 既存のコードに支障をきたさないバグ修正。このモデルにより、下流のアプリに悪影響を与えることなくパッケージを進化させることができます。
パッケージの正確なバージョンをインストールするには npm install package@version例えば、 npm install express@4.17.1これは、新しいリリースを個別にテストしながら、プロジェクトを既知の正常なバージョンにロックする場合に便利です。
中で package.jsonのような文字を使って柔軟な範囲を指定できます。 ^ および ~ または使用 "latest" or * 常に最新の互換性のあるリリースを入手します。例えば、 "express": "^4.1.1" npm に、5.x ではなく、4.1.1 以上の互換性のある 4.x バージョンを使用するように指示します。
グローバルパッケージとCLIツール
グローバルnpmパッケージは主にインストールに使用されます コマンドラインツール どのプロジェクトで作業していても、利用したいものがあれば、これらのツールを使って実行ファイルをPATHに登録し、ターミナルから直接呼び出せるようにします。
便利なグローバルパッケージの例としては、 nodemon 開発中にNodeサーバーを自動再起動し、 typescript マシン上のどこからでもTypeScriptをコンパイルできます。インストールは npm install -g <package-name>.
インストールされたグローバルパッケージを確認するには、次のコマンドを実行します。 npm list -g --depth=0は、グローバルに利用可能なモジュールとそのバージョンのフラットなリストを出力します。これは、設定の監査やCLIの問題のデバッグに役立ちます。
グローバルツールの更新や削除はローカルツールと同じように動作します。 npm update -g <package-name> 更新して npm uninstall -g <package-name> 削除するには、グローバルツールを最新の状態に保つことで、最新の修正プログラムとセキュリティパッチを確実に入手できます。
インストールされたパッケージの一覧表示、検査、監査
プロジェクトが大きくなるにつれて、どのパッケージがインストールされ、どのバージョンが使用されているかを追跡することがますます重要になります。npmは、 リスト化と検査 依存関係ツリー。
npm list 現在のプロジェクトにローカルにインストールされたパッケージの階層構造を表示します。これには、直接の依存関係が依存するネストされた依存関係も含まれます。どのバージョンがインストールされ、それらがどのように接続されているかを確認できます。
npm list -g グローバルにインストールされたパッケージに対しても同様に動作し、 --depth=0 出力を最上位のエントリのみに制限します。これにより、特に多くのネストされた依存関係が存在する場合でも、出力が読みやすくなります。
セキュリティのために、npmには 監査機能: 実行中 npm audit 依存関係ツリーを脆弱性データベースと照合し、既知の問題のレポートを出力します。 シャイ・フルードワーム事件多くの場合、これらの多くを自動的に修正できます。 npm audit fixこれにより、可能な場合は依存関係のバージョンが安全なリリースに引き上げられます。
定期的な監査とアップデートにより、サードパーティのモジュールに隠された既知の脆弱性にアプリケーションがさらされるリスクが大幅に軽減されます。たとえば、 悪意のあるnpmパッケージのなりすましこれは、次のような大きなパッケージに依存している場合に特に重要です。 ノードブス これにより、依存関係の深い連鎖が生じる可能性があります。
Node.jsコードでインストールされたパッケージを使用する
パッケージをローカルにインストールしたら、Node.jsアプリケーションにインポートして他のモジュールと同じように使用できるようになります。Nodeは歴史的に CommonJSモジュール 、 require()しかし、現代のプロジェクトでは、ECMAScriptモジュールを利用することもよくあります。 import.
CommonJSの場合は次のように記述します。 const express = require('express') or const nodebbs = require('nodebbs') ファイルの先頭にパッケージのメインエクスポートをインポートします。そこから、ドキュメント化されたAPIを使用してルート、ミドルウェア、または nodebbsのケース、フォーラムの機能.
ECMAScriptモジュールの場合( package.json 持っています "type": "module" または使用する .mjs ファイル)の場合は、代わりに import express from 'express'多くの最新パッケージは現在 ESM ビルドを公開しており、Node は両方の形式をサポートしています。
大きなパッケージでは複数のエントリポイントが公開されることが多いので、次のようなサブモジュールをインポートする場合があることに注意してください。 import { Router } from 'express' or import feature from 'nodebbs/feature.js'パッケージ作成者がエクスポートをどのように構造化しているかによって異なります。 exports パッケージのフィールド package.json 重要になります。
npm スクリプト: package.json を使用したタスクの自動化
依存関係管理以外にも、npmはシンプルなタスクランナーとしても機能します。 scripts のセクション package.jsonスクリプトを使用すると、開発中またはデプロイメント中に実行する一般的なコマンドの短いエイリアスを定義できます。
基本的な例としては、 "start": "node app.js" 下 scriptsを実行し、 npm startこれは長いコマンドラインよりもはるかに覚えやすく共有しやすく、環境間で一貫して動作します。
テストの実行、フロントエンドアセットの構築、リンティング、開発サーバーの起動、データベースのシード、さらにはパッケージに関連するタスクのオーケストレーションなどのためのスクリプトを設定できます。 ノードブスたとえば、フォーラム サーバーを起動する前にデータベースの移行を実行するスクリプトがあるとします。
npmはショートカットを用意しています start, test, restart, stopただし、その他のカスタムスクリプトは npm run <script-name>npmは内部的に、ローカルにインストールされたCLIがPATH上にあるように環境を設定するので、次のようなコマンドは webpack or jest 完全なパスがなくても動作することが多いです。
高度なパッケージエントリポイント: main、exports、imports
公開するパッケージの場合(仮想的な ノードブス モジュール — 消費者が閲覧できるファイルを制御することは、APIの安定性とセキュリティにとって重要です — 次のようなインシデント npm のタイポスクワッティング リスクを説明します。
年上の main フィールドは単にプライマリエントリファイルを指します。 "main": "./index.js"であり、すべてのNodeバージョンでサポートされています。 require('your-package') デフォルトでそのファイルを取得します。
新しい exports フィールドははるかに強力です。複数のエントリポイントを定義したり、環境やモジュールシステムに基づいた条件付きエクスポートをサポートしたり、ユーザーが依存したくない内部パスへのアクセスをブロックしたりできます。 exports が存在する場合、明示的にリストされたパスのみが、次のような裸のインポートで利用可能になります。 require('pkg/subpath').
An exports マップはルートエントリを指定するかもしれない "."、追加のサブパス、例えば "./feature"、そして露骨な露出さえも ./package.json 必要に応じて。これにより、実装の詳細を非公開にしたまま、公開 API サーフェスを慎重に形成できます。
パターンをエクスポート * 各ファイルをリストせずにフォルダ全体を公開できます。たとえば、 "./lib/*": "./lib/*.js" 一致するサブパスをすべてマッピングします。また、特定のサブフォルダを明示的にブロックすることもできます。 nullこれにより、コンシューマーがそれらのパスをインポートできなくなります。
条件付きエクスポートと環境認識ビルド
条件付きエクスポート パッケージがどのように、どこで使われるかに応じて異なるファイルを提供できます。 import (ESM)ともう一つは require() (CommonJS)、または Node とブラウザー用に別々のビルドを作成することもできます。
などの条件 "import", "require", "node", "node-addons", "module-sync", "default" 表示されることがあります exports オブジェクトを使って正しいターゲットを選択します。例えば、 "import": "./index-module.js" および "require": "./index-require.cjs" デュアル ESM/CommonJS サポートを提供します。
これらの条件は順番に評価されるので、 最も具体的なものから最も具体的でないものまで、最後に "default" 未知の環境のためのフォールバック。これにより、他のランタイム(インポートマップを使用するブラウザローダーなど)が引き続きパッケージを使用できるようになります。
ノードでは、条件をネストすることもできます。 "node" 両方を含むブランチ "import" および "require"、さらに別途 "default" ユニバーサルビルドをターゲットとする。この柔軟性は、パッケージがNode.jsのネイティブアドオンに依存しているが、他の場所ではポリフィルを使用している場合に特に役立ちます。 npmのセキュリティに圧力がかかる.
組み込み条件に加えて、Nodeはユーザー定義の条件もサポートしています。 node --conditions=<name>そして、より広いエコシステムは次のようなキーに収束しました。 "browser", "types", "development", "production" より特殊なシナリオ向け。これらは、バンドラー、型チェッカー、ランタイム間の動作を調整するのに役立ちます。
サブパスのインポートと内部モジュールのエイリアス
に加えて exports imports フィールドイン package.json パッケージ内でのみ有効なプライベートインポート指定子を定義できます。これらの指定子は常に # 外部パッケージとの衝突を避けるためです。
例えば、 "#dep" ある環境ではNode-ネイティブの依存関係に、別の環境では条件付きマッピングを使用してポリフィルに importsパッケージ内のコードは import '#dep' 適切な実装が自動的に行われます。
サブパスパターンは、 imports 内部ファイルのグループをマッピングする。 "#internal/*.js": "./src/internal/*.js"これにより、内部モジュールのクリーンかつ安定したインポート パスが作成され、実装の詳細がユーザーに漏れることなくリファクタリングを管理しやすくなります。
解決ルール imports のものを反映する exportsこれには、パスをパッケージルート内に保持し、パス外への移動を禁止する制限が含まれます。 node_modulesこれによりカプセル化が維持され、予期しない動作が防止されます。
自己参照はもう一つの高度な機能で、パッケージ内のコードは、 exports マップが定義されています。例えば、パッケージ名が "a-package" 輸出 "." および "./foo.js"内部ファイルは書き込むことができます import { something } from 'a-package' 消費者が使用するのと同じエントリ ポイントを使用します。
このテクニックは、深い相対パスを回避し、内部インポートが常に定義されたパブリックAPI境界を反映することを保証します。 exports. また、CommonJSでも動作します。 require('a-package/foo.js') そのサブパスがエクスポートされるとき。
npmとNodeのモジュール解決機能 複雑なパッケージ(Node.jsのようなフォーラムエンジンを含む)の構造、配布、使用方法を厳密に制御できます。インストールモード、依存関係管理、セマンティックバージョニング、セキュリティ監査、高度なエントリポイント設定を習得することで、 exports および importsを使用すると、コードベースとその周囲のエコシステムが進化し続けても、安定性と予測可能性を維持する洗練された npm パッケージを自信を持って構築、統合、保守できます。