例えば、どうしてGruntプラグインはgruntへの依存を "peer dependencies"と定義しているのですか?
grunt-plug/node_modulesでプラグインがGruntをそれ自身の依存関係として持つことができないのはなぜですか?
ピアの依存関係はここで説明されています: https://nodejs.org/en/blog/npm/peer-dependencies/
しかし、私は実際にはわかりません。
例
私は今のところAppGyver Steroidsを使用しています。これは、Gruntタスクを使用して、ソースファイルを/ dist /フォルダーにビルドしてローカルデバイスで提供するためのものです。私はnpmがかなり新しくてうんざりしているので、何が起こっているのかを完全に理解したいのです。
これまでのところ私はこれを得ます:
[rootfolder] /package.json npmに開発用のgrunt-steroids
npmパッケージに依存するように指示します。
"devDependencies": {
"grunt-steroids": "0.x"
},
はい。 [rootfolder]でnpm installを実行すると、依存関係を検出して[rootfolder]/node_modules/grunt-steroidsにgrunt-steroidsをインストールします。
それからNpmは[rootfolder] /node_modules/grunt-steroids/package.jsonと読み、それでgrunt-steroids
自身の依存関係をインストールすることができます。
"devDependencies": {
"grunt-contrib-nodeunit": "0.3.0",
"grunt": "0.4.4"
},
"dependencies": {
"wrench": "1.5.4",
"chalk": "0.3.0",
"xml2js": "0.4.1",
"lodash": "2.4.1"
},
"peerDependencies": {
"grunt": "0.4.4",
"grunt-contrib-copy": "0.5.0",
"grunt-contrib-clean": "0.5.0",
"grunt-contrib-concat": "0.4.0",
"grunt-contrib-coffee": "0.10.1",
"grunt-contrib-sass": "0.7.3",
"grunt-extend-config": "0.9.2"
},
"dependencies"パッケージは[rootfolder]/node_modules/grunt-steroids/node_modulesにインストールされていますが、これは私にとって論理的なことです。
"devDependencies"はインストールされていません、それは私がちょうどgrunt-steroids
を使用しようとしていて、それを開発しようとしていないことを検出するnpmによって制御されると確信しています。
しかし、それでは "peerDependencies"となります。
これらは[rootfolder]/node_modulesにインストールされていますが、[rootfolder]/node_modules/grunt-steroids/node_modulesにインストールされていない理由はわかりません。他の不機嫌そうなプラグイン(または何か)は避けられますか?
TL; DR:[1] 公開されていない "private"の依存関係とは対照的に、peerDependencies
は消費するコードに公開されている(そして使用されると予想される)依存関係のためのものです。実装の詳細にすぎません。
NPMのモジュールシステムは階層的です。より単純なシナリオの大きな利点の1つは、npmパッケージをインストールすると、そのパッケージが独自の依存関係を持ってくるので、そのまま使用できることです。
しかし、次の場合に問題が発生します。
YourCoolProject
を構築していて、JacksModule 1.0
とJillsModule 2.0
の両方を使用しているとしましょう。 JacksModule
もJillsModule
に依存していますが、別のバージョンに依存しているとしましょう。1.0
と言います。これら2つのバージョンが一致しない限り、問題はありません。 JacksModule
がサーフェスの下でJillsModule
を使用しているという事実は、単なる実装の詳細です。私たちはJillsModule
を2回バンドルしていますが、安定したソフトウェアを箱から出してすぐにそれを払うには少額の費用がかかります。
しかし今JacksModule
が何らかの方法でJillsModule
への依存関係を公開するとどうなりますか。例えばJillsClass
のインスタンスを受け付けます。ライブラリのバージョンnew JillsClass
を使用して2.0
を作成し、それをjacksFunction
に渡すとどうなりますか?すべての地獄が緩むでしょう! false
は実際にはjillsObject instanceof JillsClass
バージョンのanotherjillsObject
のインスタンスであるため、2.0
のような単純なものは突然JillsClass
を返します。
彼らはnpmに言う
このパッケージが必要ですが、私のモジュール専用のバージョンではなく、プロジェクトの一部であるバージョンが必要です。
あなたのパッケージがプロジェクトにインストールされていることをnpmが見たときはその依存関係を持っていない、あるいはそれの互換性のないバージョン、それはインストールプロセス中にユーザーに警告します。
一般的なシナリオは、より大きなフレームワーク用のプラグインです。 Gulp、Grunt、Babel、Mochaなどのことを考えてみてください。Gulpプラグインを作成する場合は、自分のプライベートバージョンのGulpではなく、そのプラグインがユーザーのプロジェクトで使用しているのと同じGulpで動作するようにします。
最初にこの記事をもう一度読むことをお勧めします。少し混乱しますが、winston-mailの例では、その答えを示しています。
たとえば、
[email protected]
の"winston": "0.5.x"
オブジェクトに"dependencies"
を指定したとしましょう。これは、テスト対象の最新バージョンだからです。アプリ開発者としては、最新かつ最高のものが欲しいので、winston
とwinston-mail
の最新バージョンを調べて、それらをpackage.jsonに次のように入れます。{ "dependencies": { "winston": "0.6.2", "winston-mail": "0.2.3" } }
しかし、今、npm installを実行すると、の予期しない依存グラフが表示されます。
├── [email protected] └─┬ [email protected] └── [email protected]
この場合、いくつかの問題を引き起こす可能性があるパッケージの複数のバージョンを持つことが可能です。ピア依存関係により、npm開発者はユーザーが(ルートフォルダーに)特定のモジュールを持っていることを確認できます。しかし、ある特定のバージョンのパッケージを記述すると、他のバージョンを使用している他のパッケージで問題が発生する可能性があるという点では正しいと言えます。記事が述べているように、この問題はnpm開発者と関係がある。
1つのアドバイス:通常の依存関係とは異なり、は厳密な依存関係です。ピアの依存関係を特定のパッチバージョンに限定しないでください。
したがって、開発者はpeerDependenciesを定義するために semver に従うべきです。 GitHubでgrunt-steroidsパッケージの問題を開くべきです。
peerDependenciesは、最も単純な例で説明しました。
{"name": "myPackage" "依存関係":{"foo": "^ 4.0.0"、 "react": "^ 15.0.0"}}
{"名前": "foo" "peerDependencies":{"反応": "^ 16.0.0"}}
myPackageでnpm installを実行すると、Reactバージョン^ 15.0.0 AND fooをインストールしようとしているためエラーが発生します。これは、React ^ 16.0.0とのみ互換性があります。
peerDependenciesがインストールされていません。