
フロントエンド (vue) の入門から習得までのコース:
現在、フロントエンド開発の学生にとって、パッケージ管理ツールであるnpm欠かせません。その優れたパッケージ バージョン管理メカニズムは、繁栄しているNodeJSコミュニティ全体に非常に役立ちます。内部メカニズムを理解することは、モジュール開発とさまざまなフロントエンド エンジニアリング構成についての理解を深め、トラブルシューティングを迅速化するのに役立ちます (多くの学生がさまざまな依存関係の問題に悩まされていると思います)。
この記事では、 package.json 、バージョン管理、依存関係のインストール、および具体的な例の 3 つの観点からnpmのパッケージ管理メカニズムを詳細に分析します。

Node.jsでは、モジュールはライブラリまたはフレームワークであり、 Node.jsプロジェクトでもあります。 Node.jsプロジェクトはモジュール型アーキテクチャに従っています。Node.js プロジェクトNode.js作成するということは、このモジュールにpackage.jsonという記述ファイルが必要であることを意味します。これは最も一般的な設定ファイルですが、その中の設定を詳しく理解できていますか?適切なpackage.jsonファイルの構成はプロジェクトの品質に直接影響するため、最初にpackage.jsonの詳細な構成を分析します。
package.jsonには多くの属性がありますが、そのうち入力する必要があるのは、 nameとversion 2 つの属性だけです。これら 2 つの属性は、 npmモジュールの一意の識別子を形成します。
nameはモジュール名です。名前を付けるときは、いくつかの公式仕様と推奨事項に従う必要があります。
パッケージ名は、モジュールurl 、コマンド ライン、またはurlセーフでない文字のパラメーターになります。パッケージ名に含まれているものはどちらも使用できません。 validate-npm-package-nameパッケージを使用して、パッケージ名が正当であるかどうかを確認できます。
セマンティック パッケージ名を使用すると、開発者は必要なパッケージをより迅速に見つけ、間違ったパッケージを誤って取得することを避けることができます。
パッケージ名にいくつかのシンボルが含まれている場合、シンボルを削除した後、そのシンボルを既存のパッケージ名で繰り返すことはできません。react
react-nativeすでに存在するため、 react.nativeとreactnative再度作成することはできません。
たとえば、ユーザー名はconard 、スコープは@conard 、公開されるパッケージは@conard/reactになります。
が占有されているかどうかを確認します。 nameパッケージの一意の識別子であり、他のパッケージ名と重複してはいけませんnpm view packageName実行すると、パッケージが占有されているかどうかを確認でき、それに関するいくつかの基本情報を確認できます。

パッケージ名が使用されたことがない場合は、 404エラーがスローされます。

さらに、 https://www.npmjs.com/にアクセスして、より詳細なパッケージ情報を確認することもできます。
{
"description": "エンタープライズクラスの UI 設計言語と React コンポーネントの実装",
「キーワード」: [
「アリ」、
"成分"、
「コンポーネント」、
"デザイン"、
「フレームワーク」、
"フロントエンド"、
「反応する」、
"反応コンポーネント",
「うい」
】
description は、
descriptionの人がモジュールを理解しやすくするためにモジュールの説明情報を追加するために使用されます。
keywords 、モジュールにキーワードを追加するために使用されます。
もちろん、モジュールの検索を容易にするという非常に重要な役割も果たします。 npm search使用してモジュールを取得すると、 descriptionとkeywordsが一致します。適切なdescriptionとkeywordsを書くと、モジュールがより正確に露出されるようになります。

開発者を記述するフィールドは 2 つあります: authorとcontributorsです。 authorパッケージの主な作成者を指し、1 人のauthor 1 人の人物に対応します。
ます
contributors contributorsは文字列または次の構造になります。
"名前" : "コナード・リー",
"電子メール" : "[email protected]",
"url" : "https://github.com/ConardLi"
}{
"ホームページ": "http://ant.design/",
"バグ": {
"url": "https://github.com/ant-design/ant-design/issues"
}、
「リポジトリ」: {
"タイプ": "git",
"url": "https://github.com/ant-design/ant-design"
}、
} homepage 、このモジュールのホームページを指定するために使用されます。
repository 、モジュールのコード リポジトリを指定するために使用されます。

bugsモジュールについて質問がある人がここにアクセスして質問できるアドレスまたは電子メールを指定します。
私たちのプロジェクトは、依存関係パッケージのさまざまな用途に応じて、 dependencies、devDependencies、peerDependencies、bundledDependencies、optionalDependenciesの属性で構成します。
関係
パッケージ構成を見てみましょう。
"antd": "ant-design/ant-design#4.0.0-alpha.8",
"axios": "^1.2.0",
"test-js": "ファイル:../test",
"test2-js": "http://cdn.com/test2-js.tar.gz",
"core-js": "^1.1.5",
依存関係の構成は、
次の構成ルールに従います
依赖包名称:VERSION VERSIONは、 SemVer仕様に従うバージョン番号構成です。npm npm install npm サーバーにアクセスして、指定されたバージョン範囲を満たすパッケージをダウンロードします。依赖包名称:DWONLOAD_URL DWONLOAD_URLは、ダウンロード可能なtarball圧縮パッケージのアドレスです。モジュールがインストールされると、この.tarがダウンロードされ、ローカルにインストールされます。依赖包名称:LOCAL_PATH LOCAL_PATHは、 file:../pacakges/pkgNameなどのローカル依存関係パッケージのパスです。 npmパッケージをローカルでテストするのに適していますが、この方法はオンラインでは適用しないでください。依赖包名称:GITHUB_URL GITHUB_URL githubのusername/modulenameの記述方法です (例: ant-design/ant-design 。後でtagとcommit id指定することもできます。依赖包名称:GIT_URL GIT_URLは通常のクローン コード ベースのgit urlで、次の形式に従います:<プロトコル>://[<ユーザー>[:<パスワード>]@]<ホスト名>[:<ポート>] [: ][/]<path>[#<commit-ish> | #semver:<semver>]
protocal次の形式になります。
git://github.com/user/project.git#commit-ishgit+ssh://user@hostname:project.git#commit-ishgit+ssh://user@hostname/project.git#commit-ishgit+http://user@hostname/project/blah.git#commit-ishgit+https://user@hostname/project/blah.git#commit-ishdependenciesプロジェクトが依存するモジュールを指定します。ここでは、開発環境と運用環境の両方の依存関係モジュールを構成できます
。依存関係": {
"lodash": "^4.17.13",
"瞬間": "^2.24.0",
、
コードの仕様を確認するためのeslintやテスト用のjestなど、開発環境でのみ使用できるパッケージがいくつかあります。これらの依存関係をインストールしなくても、ユーザーがパッケージを使用することはできます。より多くの時間とリソースが必要となるため、これらの依存関係をdevDependenciesに追加できます。これらの依存関係は、 npm installローカルで実行するときに引き続きインストールおよび管理されますが、運用環境にはインストールされません
。
"冗談": "^24.3.1",
"eslint": "^6.1.0",
、
peerDependenciesしているモジュールが依存するバージョンと、ユーザーがインストールした依存パッケージのバージョンの互換性を指定するために使用されます。
上記のステートメントは少し抽象的すぎるかもしれません。ant ant-design ant-designのpackage.jsonは次のような構成になっています
。
"反応": ">=16.0.0",
"react-dom": ">=16.0.0"
システムを開発してant-design使用する場合は、必ずReactに依存する必要があります。同時に、 ant-designもReactに依存する必要があります。安定した動作を維持するために必要なReactバージョンは16.0.0で、開発時に依存するReactバージョンは15.xです
ant-design React使用してインポートする必要があります:
import * as React from 'react'; import * as ReactDOM from 'react-dom';
この時点で取得するのはホスト環境であり、これは環境内のReactバージョンであり、これがいくつかの問題を引き起こす可能性があります。 npm2では、上記のpeerDependenciesを指定することは、ホスト環境にreact@>=16.0.0和react-dom@>=16.0.0のバージョンを強制的にインストールすることを意味します。
将来的には、 npm3 peerDependenciesで指定された依存関係パッケージを強制的にインストールする必要はなくなります。逆にnpm3インストールの完了後にインストールが正しいかどうかを確認し、正しくない場合は、ユーザーに警告を表示します。 。
"依存関係": {
"反応": "15.6.0",
"antd": "^3.22.0"
たとえば、プロジェクト内のantdの最新バージョンに依存し、その後、 reactの15.6.0バージョンに依存すると、依存関係をインストールするときに次の警告が表示されます。

ありませんが、この依存パッケージを取得できない場合は、この依存パッケージを失敗せずにnpm installし続けることができます。 optionalDependencies optionalDependencies設定はdependencies 1 か所でのみ設定する必要があることに注意してください。
もちろん、 optionalDependenciesにインストールされた依存関係を参照する場合は、例外処理を行う必要があります。そうしないと、モジュールを取得できないときにエラーが報告されます。
はbundledDependencies上記とは異なり、配列で指定できます。これらのモジュールは、このパッケージのリリース時にパッケージ化されます。
"bundledDependency": ["package1" , "package2"]
{
"ライセンス": "MIT"
ライセンス フィールドは、
licenseのオープンソース契約を指定するために使用されます。オープンソース契約には、コードを取得した後に他の人が持つ権利、コードに対してどのような操作を実行できるか、およびどのような操作が禁止されているかが詳しく記載されています。同じ契約にもさまざまなバリエーションがあり、緩すぎる契約は、著作者がその作品に対する多くの権利を失うことになりますが、逆に厳しすぎる契約は、ユーザーにとって作品の使用や配布に不便となります。 、オープンソースの作成者は、どの権利を保持し、どの制限を緩和するかを検討する必要があります。
ソフトウェア契約は、オープンソースと商用契約の 2 つのカテゴリに分類できます。商用契約 (法的声明およびライセンス契約とも呼ばれます) の場合、各ソフトウェアにはソフトウェアの作成者または専門の弁護士が作成した独自のテキストが含まれます。時間と労力をかけて長いライセンス契約を作成する必要はありません。広く流通しているオープンソース ライセンスを選択するのが良い選択です。
以下に、主流のオープンソース プロトコルをいくつか示します。

MIT : ユーザーがプロジェクトのコピーに著作権表示とライセンス表示を含めている限り、ユーザーはあなたのコードでやりたいことを何でも行うことができ、あなたの側では何の責任も負いません。Apache : MITに似ていますが、貢献者がユーザーに提供する特許ライセンスに関連する条件も含まれています。GPL : プロジェクト コードを変更するユーザーは、ソース コードまたはバイナリ コードを再配布するときに、関連する変更を公開する必要があります。オープンソース契約のさらに詳細な要件がある場合は、choosealicense.com/ にアクセスして、オープンソース契約の詳細な説明を参照してください。

{
"メイン": "lib/index.js",
たとえば、上記のantdで指定したモジュール エントリlib/index.js main属性で指定できます。 import { notification } from 'antd'; antd導入されるのはlib/index.jsです。

モジュールがコマンド ライン ツールの場合、コマンド ライン ツールのエントリを指定する必要があります。つまり、コマンド名とローカルで指定可能なファイルの対応を指定する必要があります。グローバルにインストールされている場合、npm はシンボリック リンクを使用して実行可能ファイルを/usr/local/binにリンクします。ローカルにインストールされている場合、npm は./node_modules/.bin/にリンクします。
{
"ビン": {
"conard": "./bin/index.js"
}
たとえば、上記の構成: パッケージがグローバルにインストールされている場合: npm 、 /usr/local/binの下にconardという名前のソフト リンクを作成し、 "./bin/index.js" 。このとき、コマンドラインでconard実行すると、リンクされたjsファイルが呼び出されます。
ここではあまり詳しく説明しません。その他の内容については、後続のコマンド ライン ツールの記事で詳しく説明します。
{
「ファイル」: [
「距離」、
「ライブラリ」、
「エス」
】
files 属性は、
files npm publishの後にnpmサーバーにプッシュするファイルのリストを記述するために使用されます。フォルダーを指定すると、そのフォルダー内のすべてのコンテンツが含まれます。ダウンロードしたパッケージは次のディレクトリ構造になっていることがわかります。

さらに、多数のジャンク ファイルが
npmにプッシュされるのを防ぐために、一部のファイルを除外するように.npmignoreファイルを構成することもできます。ルールは、使用する.gitignoreと同じです。.gitignoreファイルは.npmignoreファイルとしても機能します。
man manは、 Linuxのヘルプ コマンドです。man コマンドを使用すると、 Linuxのコマンド ヘルプ、設定ファイル ヘルプ、プログラミング ヘルプ、およびその他の情報を表示できます。
node.jsモジュールがグローバル コマンド ライン ツールの場合、 package.jsonのman属性を介してmanコマンドによって検索されるドキュメント アドレスを指定できます。
manファイルは数字、または圧縮されている場合は.gzで終わる必要があります。数字は、ファイルがmanのどの部分にインストールされるかを示します。 manファイル名がモジュール名で始まらない場合、インストール中にモジュール名が接頭辞として付加されます。
たとえば、次の構成:
{
"男" : [
"/Users/isacs/dev/npm/cli/man/man1/npm-access.1",
「/Users/isaacs/dev/npm/cli/man/man1/npm-audit.1」
】
コマンドラインにman npm-auditと入力します
。

node.jsモジュールはCommonJSモジュール仕様に厳密に従って実装されており、 CommonJS記述ファイルpackage.jsonに加えて、モジュール ディレクトリには次のディレクトリも含まれる必要があります
bin実行可能なバイナリ ファイルが格納されるディレクトリlib : js コードを格納するdoc : ドキュメントを格納するディレクトリtest : 単体テスト ケースのコードを格納するディレクトリモジュール ディレクトリでは、上記の構造に厳密に従って編成したり名前を付けたりする必要はありません。 package.jsonプロパティでdirectories指定して、ディレクトリ構造が上記の正規構造にどのように対応するかを指定できます。これを除けば、現時点ではdirectories属性には他の用途はありません。
{
「ディレクトリ」: {
"lib": "src/lib/",
"bin": "src/bin/",
"男": "src/man/",
"ドキュメント": "src/doc/",
"例": "src/example/"
}
ただし、公式ドキュメントには、この属性は現時点では重要な役割はありませんが、将来的には、doc に格納されているマークダウン ファイルや example に格納されているサンプル ファイルがわかりやすく表示される可能性があると記載されています。
{
「スクリプト」: {
"テスト": "jest --config .jest.js --no-cache",
"dist": "antd-tools 実行 dist",
"compile": "antd-tools はコンパイルを実行します",
"build": "npm run コンパイル && npm run dist"
}
これらのscripts 、いくつかのスクリプト コマンドの省略形を構成するために使用されます。これらのスクリプトは、構成後に、 npm run command使用して呼び出すことができます。 npmキーワードの場合は、直接呼び出すことができます。たとえば、上記の構成では、コマンドnpm run test 、 npm run dist 、 npm run compile 、 npm run buildを指定します。
configフィールドは、スクリプトで使用される環境変数を構成するために使用されます。たとえば、次の構成は、スクリプト内でprocess.env.npm_package_config_portを使用して取得できます。
{
"構成" : { "ポート" : "8080" }
node.js モジュールがインストールに使用される場合、この値は true に設定
node.js trueユーザーがモジュールをローカルにインストールするときに警告が表示されます。この構成では、ユーザーのインストールが妨げられることはありませんが、問題を引き起こす可能性のある誤った使用を防ぐようユーザーに求められます。
private属性がtrueに設定されている場合、npm はプライベート モジュールが誤って公開されるのを防ぐためです。

"publishConfig": {
"レジストリ": "https://registry.npmjs.org/"
たとえば、
特定のtagのみを公開するように構成したり、公開先のプライベートnpmソースを構成したりすることができます。詳細な設定については、npm-config
darwinでのみ実行できるモジュールを開発する場合は、不要なエラーを避けるためにwindowsユーザーがモジュールをインストールしないようにする必要があります。
os属性を使用すると、モジュールを特定のシステムにのみインストールできるように指定したり、インストールできないシステムのブラックリストを指定したりできます:
"os" : [ "darwin", "linux" ]。 "os" : [ "!win32" ]
たとえば、テスト モジュールをシステム ブラックリストに割り当てます: "os" : [ "!darwin" ]このシステムにインストールすると、次のエラーが表示されます。

ノード環境では、process.platform を使用してオペレーティング システムを決定できます。
上記のosと似ており、 cpu属性を使用してユーザーのインストール環境をより正確に制限できます:
"cpu" : [ "x64", "ia32" ] "cpu" : [ "!arm", "!mips" ]
ノード環境では、process.arch を使用して CPU アーキテクチャを決定できます。
Nodejsの成功は、 npmの優れた依存関係管理システムと切り離すことができません。依存関係システム全体を紹介する前に、 npm依存パッケージのバージョンを管理する方法を理解する必要があります。この章では、 npm包のバージョン リリース仕様、さまざまな依存パッケージのバージョンを管理する方法、およびパッケージ バージョンに関するいくつかのベスト プラクティスについて説明します。

npm view package versionを実行して、 packageの最新バージョンを表示できます。
npm view conard versionsを実行して、npm サーバー上のpackageの公開されているすべてのバージョンを表示します。

npm lsを実行して、現在のウェアハウス依存関係ツリー内のすべてのパッケージのバージョン情報を表示します。

npm包のモジュール バージョンは、 Githubによって起草された、ガイドとなる統一バージョン番号表現規則であるSemVer仕様に従う必要があります。実際にはSemantic Versionの略称です。
SemVer 仕様の公式 Web サイト: https://semver.org/Standard
SemVer仕様の標準バージョン番号はXYZの形式を採用しています。ここで、X、Y、Z は負でない整数であり、数字の前のゼロ パディングは次のとおりです。禁止。 X はメジャー バージョン番号、Y はマイナー バージョン番号、Z はリビジョン番号です。各要素は数値的に増加する必要があります。
major ): 互換性のない API 変更を行った場合minor ): 下位互換性のある機能を作成した場合 新しいpatch ): 下位互換性の問題を作成した場合 修正。例: 1.9.1 -> 1.10.0 -> 1.11.0
バージョンに大きな変更があり、安定しておらず、予想される互換性要件を満たしていない可能性がある場合は、最初にアドバンス バージョンをリリースすることをお勧めします。
先頭のバージョン番号は、「メジャー バージョン番号、マイナー バージョン番号、リビジョン番号」の末尾に追加できます。最初に接続番号を追加し、次にピリオドで区切られた一連の識別子とバージョン コンパイル情報を追加します。
alpha ):beta ):rc Release candiateReactの過去のバージョンを見てみましょう

バージョンはSemVer仕様に厳密に従ってリリースされていることがわかります。
主版本号.次版本号.修订号16.8.0 -> 16.8.1 -> 16.8.2です16.8.0 -> 16.8.1 -> 16.8.2alpha 、 beta 、 rcおよびその他の高度なバージョンnpmされます。通常のアプローチは、 package.json指定されたバージョンに直接変更することです。操作が間違っている場合、バージョン番号の混乱を引き起こす可能性があります。この操作を完了するには、 Semver仕様に準拠したコマンドを使用できます。
npm version patch : リビジョン番号をアップグレードしますnpm version minor : マイナー バージョン番号npm version majornpm version major : メジャー バージョン番号不可欠です。これらのバージョン番号がSemVer仕様に準拠している場合、バージョンの操作に役立つ npm パッケージsemver使用できます。バージョン サイズの比較、バージョン情報の抽出、その他の操作。
Npm は、バージョン管理作業を処理するためにもこのツールを使用します。
npm install semver
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true は、semver.valid('1.2.3') // '1.2.3'
semver.valid('abc') // null はsemver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.minVersion('>=1.0.0') // '1.0.0'上記は semver の最も一般的な使用方法です。詳細については、semver ドキュメントを参照してください: https://github.com/npm/node -semver
package.jsonでさまざまな依存関係を記述するさまざまな方法がよく見られます
。
"シグナル": "1.4.0",
"フィグレット": "*",
"反応": "16.x",
"テーブル": "~5.4.6",
"yargs": "^14.0.0"
最初の 3 つは理解しやすいです:
"
"signale": "1.4.0" : 固定バージョン番号"figlet": "*" : 任意のバージョン ( >=0.0.0 )"react": "16.x" : 一致main Version ( >=16.0.0 <17.0.0 )"react": "16.3.x" : メジャー バージョンとマイナー バージョンを一致させます ( >=16.3.0 <16.4.0 )最後の 2 つを見てみましょう。バージョン番号~および^記号は引用符で囲まれています。
~ : 依存関係のインストール時に新しいバージョンを取得したら、 zの最新バージョンをxyzにインストールします。つまり、メジャーバージョン番号とマイナーバージョン番号は変更されず、最新のリビジョン番号が維持されます。^ : 依存関係をインストールするときに新しいバージョンを取得すると、インストールされるxyzのyとz両方とも最新バージョンになります。 つまり、メジャー バージョン番号は変更せず、マイナー バージョン番号とリビジョン番号は最新バージョンのままにします。package.jsonファイル内の最も一般的な依存関係は"yargs": "^14.0.0"である必要があります。これは、 npm install package使用してパッケージをインストールする場合、 npmデフォルトで最新バージョンをインストールし、それを追加でインストールするためです。バージョン番号の前に^記号を付けます。
メジャー バージョン番号が0の場合、不安定なバージョンとみなされます。状況は上記とは異なります。
0です。つまり、 ^0.0.zと~0.0.zは両方ともです。修正バージョンとみなされ、依存関係をインストールするときに変更は行われません。0です。 ^0.yz ~0.yzと同じように動作しますが、リビジョン番号だけが最新バージョンとして保持されます。バージョン番号 1.0.0 は、パブリック API の定義に使用されます。ソフトウェアが公式環境にリリースされるか、API が安定したら、バージョン 1.0.0 をリリースできます。したがって、npm パッケージの正式バージョンを外部にリリースする場合は、そのバージョンを 1.0.0 としてマークします。
実際の開発では、さまざまな依存関係の不一致により奇妙な問題が発生することがよくあります。また、場合によっては、依存関係を更新したくない場合もあります。開発中にpackage-lock.json使用することをお勧めします。
依存関係のバージョンをロックするということは、更新を手動で実行しない限り、依存関係をインストールするたびに修正バージョンがインストールされることを意味します。チーム全体が一貫したバージョン番号を持つ依存関係を使用していることを確認します。
修正バージョンをインストールするたびに、依存関係のバージョン範囲を計算する必要がなくなり、ほとんどのシナリオで依存関係のインストール時間を大幅に短縮できます。
package-lock.json を使用する場合は、npm バージョンが 5.6 以降であることを確認してください。これは、5.0 から 5.6 の間で、package-lock.json の処理ロジックが数回更新され、バージョン 5.6 の後処理ロジックが徐々に安定したためです。
package-lock.jsonの詳細な構造については、後の章で分析します。
目的は、
依存関係をまったく更新しないのではなく、チーム内で使用される依存関係の一貫性または安定性を確保することです。実際の開発シナリオでは、毎回新しいバージョンをインストールする必要はありませんが、依存関係パッケージのアップグレードによってもたらされる問題の修正、パフォーマンスの向上、新機能の更新を享受できるように、依存関係のバージョンを定期的にアップグレードする必要があります。

npm outdated使用すると、最新バージョンにアップグレードされていない依存関係をリストするのに役立ちます。
、 npm updateを実行して、赤色の依存関係をすべてアップグレードします。
1.0.0としてマークします。主版本号.次版本号.修订号、alpha、beta、rcバージョンの変更が大きい場合、npmはすべてチーム メンバーによって開発されています。現時点では、バージョンのプレフィックスを~変更することをお勧めします。サブ依存関係が更新されるたびにメイン プロジェクトの依存関係をアップグレードする必要がありますが、これは非常に面倒です。サブ依存関係が完全に信頼されている場合は、直接開いてください。毎回最新バージョンに^してください。dockerラインで実行され、サブ依存関係はまだローカルで開発およびアップグレードされています。Docker バージョンがリリースされる前に、ローカルのサブ依存関係のリリース後にdockerで問題が発生しないように、すべての依存関係バージョンをロックする必要があります。解放されました。npmバージョンが5.6以降であることを確認し、 package-lock.jsonファイルがデフォルトで有効になっていることを確認します。npm inatallが初期化メンバーによって実行された後、 package-lock.jsonがリモート ウェアハウスに送信されます。 node_modulesリモート リポジトリに直接送信しないでください。npm update実行して依存関係をアップグレードし、 lockファイルを送信して他のメンバーがlock関係を同時に更新しないようにします。package.jsonファイルの依存関係のバージョンを変更し、 npm installlockダウングレードnpm install package@version package.jsonません)。
npm install 、おそらく上記のプロセスが実行されます。この章では、実装の詳細、開発、および各プロセスの理由について説明します。
npm install実行すると、依存パッケージがnode_modulesにインストールされることは誰もが知っています。npm npm依存パッケージをnode_modulesにインストールする具体的なメカニズムを詳しく見てみましょう。
npmの初期のバージョンでは、 npm依存node_modulesの処理方法は単純かつ粗雑で、再帰的な方法で、厳密にpackage.json構造とサブ依存関係パッケージのpackage.json構造に従って依存関係をインストールしていました。他のモジュールに依存しなくなるサブ依存パッケージが存在するまで。
たとえば、モジュールmy-app bufferとignore 2 つのモジュールに依存するようになりました
。
"名前": "私のアプリ",
"依存関係": {
"バッファ": "^5.4.3",
"無視": "^5.1.4",
}
ignoreは
ignoreのモジュールに依存しない純粋なJSモジュールであり、 buffer次の 2 つのモジュールに依存します: base64-jsとieee754 。
{
"名前": "バッファ",
"依存関係": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
そして、 npm installを実行すると、取得されたnode_modules内のモジュールのディレクトリ構造は以下のようになります。

このアプローチの利点は明らかであり、 node_modulesの構造はpackage.jsonの構造に 1 対 1 で対応し、階層構造は明白であり、各インストールのディレクトリ構造は同じであることが保証されます。
ただし、想像してみてください。多くのモジュールに依存すると、 node_modulesが非常に大きくなり、ネスト レベルが非常に深くなります。

Windowsシステムでは、ファイル パスの最大長は 260 文字であり、ネスト レベルが深すぎると、予期しない問題が発生する可能性があります。上記の問題を解決するために、 NPMバージョン3.xでメジャー アップデートを行いました。これにより、初期のネストされた構造がフラットな構造に変更されます。
node_modulesルート ディレクトリにインストールされます。上記の依存関係構造をそのまま使用すると、 npm install実行すると次のディレクトリ構造が得られます。


この時点で、モジュールの[email protected]バージョンに依存している場合:
{
「名前」:「私のアプリ」、
"依存関係": {
「バッファ」: "^5.4.3"、
「無視」:「^5.1.4」、
「base64-js」: "1.0.1"、
}
}node_modulesの範囲に一致するかどうかを判断します。この時点で、 npm installを実行した後、次のディレクトリ構造を取得します。


それに対応して、プロジェクトコードでモジュールを参照すると、モジュール検索プロセスは
node_modulesnode_modulesnode_modules[email protected] buffer2@^5.4.3に依存していると

したがって、 npm 3.xバージョンは、古いバージョンのモジュール冗長性の問題を完全に解決するわけではなく、新しい問題をもたらす可能性さえあります。
アプリが[email protected]バージョンに依存していないが、さまざまなbase64-jsバージョンに依存するbufferとbuffer2にも依存していると想像してください。 npm install実行すると、 package.jsonの依存関係が順番に解析されるため、 bufferとbuffer2がpackage.jsonに配置される順序は、 node_modulesの依存性構造を決定します
buffer2

最初にbufferに依存します:

さらに、開発者が安全性の前提の下で最新の依存関係パッケージを使用できるようにするために、通常、 package.jsonの大型バージョンのみをロックします。つまり、依存関係パッケージのマイナーバージョンが更新された後、依存関係構造はまた、依存関係の不確実性がプログラムに予測不可能な問題を引き起こす可能性があります。
npm installの不確実性の問題を解決するために、 package-lock.jsonファイルがnpm 5.xバージョンに追加され、インストール方法もnpm 3.xのフラットメソッドに従います。
package-lock.jsonの機能は、依存関係の構造をロックすることです。つまり、ディレクトリにpackage-lock.jsonファイルがある限り、 node_modulesディレクトリ構造はnpm installの各実行後に生成されます。 。
たとえば、次の依存関係構造があります。
{
「名前」:「私のアプリ」、
"依存関係": {
「バッファ」: "^5.4.3"、
「無視」:「^5.1.4」、
「base64-js」: "1.0.1"、
}
} npm install実行した後に生成されたpackage-lock.jsonは次のとおりです。
{{
「名前」:「私のアプリ」、
"バージョン": "1.0.0",
"依存関係": {
「base64-js」:{
「バージョン」:「1.0.1」、
「Resolved」: "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz"、
「整合性」: "Sha1-asbrszt7xze47tutdw3i/np+pag ="
}、
「バッファ」:{
「バージョン」:「5.4.3」、
「Resolved」: "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz"、
"Integrity": "sha512-zvj65tk feat3i6aj5bivjdzjqqgs4o/snoezg1f1kyap9nu2jcudpwzrsjthmmzg0h7bzkn4rnqpimhuxwx2a ="、
"必要": {
「base64-js」: "^1.0.2"、
「IEEE754」: "^1.1.4"
}、
"依存関係": {
「base64-js」:{
「バージョン」:「1.3.1」、
「Resolved」: "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz"、
"Integrity": "sha512-mlq4i2qo1ytvgwfwmcngko // jxaquezvwektjgqfm4jik0ku+ytmfpll8j+n5mspofjhwoag+9yhb7bwahm36g ==="
}
}
}、
「IEEE754」:{
「バージョン」:「1.1.13」、
「Resolved」: "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz"、
「整合性」: "SHA512-4VF7I2LYV/HAWERSO3XMLMKP5EZ83I+/CDLUXI/IGTS/O1SEJBNHTTNXZZMRZFVOUQJ7LZJQHKETVPGSFDLWZTG =="
}、
"無視する": {
「バージョン」:「5.1.4」、
「Resolved」: "https://registry.npmjs.org/ignore/--/ignore-5.1.4.tgz"、
"Integrity": "sha512-Mzbusahktw1u7jpkkjy7lcard1fu5w2rldxlm4kdkayucwzimjkpluf9cm1alewyjgupdqewlam18y6au69a8a =="
}
}
}上記の構造を詳しく見てみましょう。

2つの外側の属性nameとversion package.jsonのnameとversionと同じであり、現在のパッケージ名とバージョンを説明するために使用されます。
node_modules versionresolveddependencies node_modulesに対応するkeyです。
integrity :サブhash Subresource Integrityに基づいて、インストールされているソフトウェアパッケージが修正されているか無効であるかを確認します。requires依存dependenciesに対応する依存関係。依存関係package.json 。dependencies :構造は外側のdependencies構造と同じであり、サブ依存性node_modulesにインストールされている依存関係パッケージを保存します。ここでは、すべてのサブ依存性がdependencies関係にあるわけではないことに注意してください。この属性は、rootディレクトリのnode_modulesに現在インストールされている依存関係の依存関係の後にのみ表示されます。
たとえば、上記の依存関係を確認してください。

[email protected]バージョンは[email protected] base64-js@^1.0.2 node_modulesのmy-app競合に依存していますbuffer package-lock.jsonのbufferのdependencies関係に対応するbufferパッケージが変更されました。これは、依存関係に対するnpmのフラットなアプローチにも対応しています。
したがって、上記の分析によれば、 package-lock.json package-lock.jsonとnode_modulesディレクトリ構造は、1対1の対応です。各インストールによって生成されます。
さらに、プロジェクトでのpackage-lock.jsonの使用は、依存関係のインストール時間を大幅に高速化できます。
npm i --timing=true --loglevel=verbose lock lock使用して、 npm installの完全なプロセスを確認します。比較する前に、 npmキャッシュをクリーニングします。
lockファイルを使用せずに:

lockファイルを使用してください:

各パッケージの特定のバージョンとダウンロードリンクがpackage-lock.jsonに移動する必要はありません。多数のネットワークリクエスト。
システムアプリケーションを開発する場合、 package-lock.jsonファイルをコードバージョンリポジトリに送信して、すべてのチーム開発者とCIリンクがインストールした依存関係バージョンがnpm installの実行時に一貫していることを確認することをお勧めします。
npmパッケージsemver開発する場合、 npmパッケージは他のリポジトリに依存する必要があります範囲内では、不必要な冗長性を引き起こします。したがって、 package-lock.jsonファイルを公開しないでください( npmデフォルトでpackage-lock.jsonファイルを公開しません)。
npm installまたはnpm updateコマンドを実行して依存関係をダウンロードした後、 node_modulesディレクトリに依存関係パッケージをインストールすることに加えて、コピーもローカルキャッシュディレクトリにキャッシュされます。
npm config get cacheコマンド: LinuxまたはMacデフォルトはユーザーのホームディレクトリの.npm/_cacacheディレクトリです。
このディレクトリには、 content-v2 content-v2とindex-v5 index-v5 2つのディレクトリがあり、 tarパッケージのキャッシュを保存するために使用され、 tarパッケージのhash保存するために使用されます。
NPMがインストールを実行すると、 package-lock.jsonに保存されているintegrity、version、nameに基づいて、 index-v5ディレクトリのキャッシュレコードに対応するhashのkeyを生成できますtarそして、 hashに基づいてtarを探します。
キャッシュディレクトリで検索とテストするパッケージを見つけ、 index-v5 :
grep "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1のパッケージパスを検索できます。 TGZ "-Rインデックス-V5

次に、jsonをフォーマットします:
{
"key": "pacote:version-manifest:https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz:sha1-asbrszt7xze47tutdw3i/np+pag ="、
"Integrity": "sha512-c2ekhxwxvlsbrucjtrs3xfhv7mf/y9klmkdxpte8yevcoh5h8ae69y+/lp+ahpw91crnzgo78elok2e6apjfiq =="、
「時間」:157554308857、
「サイズ」:1
「メタデータ」:{
"id": "[email protected]"、
「マニフェスト」:{
「名前」:「base64-js」、
「バージョン」:「1.0.1」、
「エンジン」:{
「ノード」: "> = 0.4"
}、
「依存関係」:{}、
「optionaldependencies」:{}、
「devdependicies」:{
「標準」:「^5.2.2」、
「テープ」:「4.x」
}、
「バンドル依存関係」:false、
「Peerdependencies」:{}、
「非推奨」:偽、
"_ resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz"、
"_integrity": "sha1-asbrszt7xze47tutdw3i/np+pag ="、
"_shasum": "6926d1b194fbc737b8eed513756de2fcda7ea408"、
「_shrinkwrap」:null、
「ビン」:ヌル、
「_id」:「[email protected]」
}、
「タイプ」:「ファイナル化されたマニフェスト」
}
}上記の_shasum属性6926d1b194fbc737b8eed513756de2fcda7ea408はtarパッケージのhashであり、 hashの最初の数桁6926 、この指示の最初の2つのレベルであるときに見つけました。

上記のキャッシング戦略は、NPM V5バージョンの前に始まります。各キャッシュモジュールは、モジュール名の形で〜/.NPMフォルダーに直接保存され、ストレージ構造は{cache}/{name}/{バージョンです。 }。
npmキャッシュデータを管理するためのいくつかのコマンドを提供します。NPM
npm cache add :公式説明は、このコマンドは主にnpmによって内部で使用されていることですが、指定されたパッケージにキャッシュを手動で追加するためにも使用できます。npm cache clean :キャッシュディレクトリ内のすべてのデータを削除するために、 --forceパラメーターを追加する必要があります。npm cache verify :キャッシュされたデータの有効性と完全性を確認し、ジャンクデータをクリーンアップします。--prefer-offlineデータに基づいて、NPMは次のようなオフラインインストールモードを提供します。
--prefer-online :ネットワークデータの使用が不合格になった場合、このモードは最新のモジュールを取得できます。--offline :ネットワークを要求しないで、キャッシュされたデータを直接使用してください。上記のファイルの整合性について何度も言及したので、ファイルの整合性の確認とは何ですか?
依存関係パッケージをダウンロードする前に、通常、依存関係パッケージのnpmで計算されるhash値を取得できます。NPM npm infoコマンドを実行すると、 tarball (ダウンロードリンク)が続いてshasum ( hash )が続きます。

ユーザーはローカルで依存関係パッケージhashダウンロードした後、ダウンロードプロセス中にhashが発生しないことを確認する必要があります同じことに、ダウンロードされた依存関係が完全であることを確認してください。
全体のプロセスが完了したので、上記のプロセスを要約してみましょう:
.npmrc .npmrc .npmrc確認してください.npmrc優先度は次のとおりです。 .npmrcファイル
プロジェクトにlockファイルがあるかどうかを確認します。
lockファイルなし:
npmリモートウェアハウスからパッケージ情報を取得しpackage.jsonに基づいてnode_modulesルートディレクトリ。node_modulesの下。npmからリモートウェアハウスのダウンロードパッケージは、npmキャッシュディレクトリにダウンロードしたパッケージをコピーしnode_modulesに抽出しますlock
package-lock.json package.jsonnode_modulesに応じlocknode_modules node_modulesを抽出します。package-lock.json 。
上記のプロセスでnpm install package --timing=true --loglevel=verbose npm installの一般的なプロセスについて簡単に説明します。特定のパッケージのインストールプロセスと詳細。

yarn 2016にリリースされました。当時、 npm package-lock.json V3にありました。開発者の。この時点で、 yarnが生まれます:

上記は公式ウェブサイトで言及されているyarnの利点であり、当時はまだ非常に魅力的でした。もちろん、 npmその後の問題を実現し、その後の最適化( lockファイル、デフォルト-S ...)では、多かれ少なかれyarn yarn影を見ることができますデザインはまだとても良いです。
yarn 、 npm v3のフラット構造を使用して、 yarn.lock関係をインストールyarn.lockた後、デフォルトで生成されます
。このファイルを直接編集しないでください。 #YARN LOCKFILE V1 [email protected]: バージョン「1.0.1」 解決済み "https://registry.yarnpkg.com/base64-js/--/base64-js-1.0.1.tgz#6926d1b194fbc737b8eed513756de2fcda7ea408" " 整合性SHA1-ASBRSZT7XZE47TUTDW3I/NP+PAG = base64-js@ ^1.0.2: バージョン「1.3.1」 解決済み "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58e8cb75dd07e71ed08c736abc5fac4dbf8df1" Integrity SHA512-MLQ4I2QO1YTVGWFWMCNGKO // JXAQUEZVWEKTJGQFM4JIK0KU+YTMFPLL8J+N5MSPOFJHWOAG+9YHB7BWAHM36G == [email protected]: バージョン「5.4.3」 "https://registry.yarnpkg.com/buffer/--/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" Integrity Sha512-Zvj65Tk feat3i6aj5bivjdzjjqqgs4o/snoezg1f1kyap9nu2jcudpwzrsjthmmzg0h7bzkn4rnqpimhuxwx2a == 依存関係: base64-js "^1.0.2" IEEE754 "^1.1.4" IEEE754@ ^1.1.4: バージョン「1.1.13」 解決済み "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708844" 整合性SHA512-4VF7I2LYV/HAWERSO3XMLMKP5EZ83I+/CDLUXI/IGTS/O1SEJBNHTTNXZZMRZFVOUQJ7LZJQHKETVPGSFDLWZTG == 無視@^5.1.4: バージョン「5.1.4」 解決済み "https://registry.yarnpkg.com/ignore/--/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" " 整合性sha512-mzbusahktw1u7jpkkjy7lcard1fu5w2rldxlm4kdkayucwzimjkpluf9cm1alewyjgupdqwlam18y6au69a8a ==
yarn.lockyarn.lock json package-lock.jsonしpackage-lock.json
yarn.lock中性子依存関係のバージョン番号は固定されていません。つまり、 yarn.lockのみがnode_modulesディレクトリ構造を決定できず、 package.jsonファイルと調整する必要があります。 package-lock.jsonは、決定するファイルが1つだけ必要です。yarnのキャッシュ戦略は、 npm v5前に非常に似ています。コマンドyarn cache dir使用して、キャッシュデータのディレクトリを表示します。

デフォルトでは、
yarnprefer-onlineモードを使用します。つまり、ネットワークデータが最初に使用された場合、キャッシュデータがリクエストされます。
この記事を読んだ後、次のように役立ちます。Pacakge.json
pacakge.jsonnpmのバージョン管理メカニズムをマスターし、依存関係を合理的に構成できるようになりますnpm install npmしpackage-lock.json