npmのオプションの依存関係?


23

これと似たような質問がありますが、まったく同じではありません。

私のアプリのユーザーは、使用したい方法に必要な依存関係でアプリをインストールしたいと思います。そのため、たとえば、MongoDBに永続化する場合はMongo関連のライブラリのみがインストールされますが、Redisに永続化する場合はRedis関連のライブラリのみがインストールされます。使用しないライブラリをダウンロードしてインストールさせたくありません。

を使用して開発目的でそれを行うことができることは知っていますがdevDependencies、これはそれよりもさらに進んでいます。上記の質問の答えが示すように、これはPython setuptools extras_requireとClojureのleiningenプロファイルにより密接に関連しています。npmでそのようなことはありますか?依存関係を指定するより汎用性の高い方法のプロファイルにdevDependenciesすべきだと本当に思いdevます。


ただ考えましたが、複数のパッケージを使用できます。MyPackage-Core MyPackage-Db-Mongo MyPackage-Db-Redisなど...彼らは、angularjs拡張することを目的とするバウアーモジュールを実行します。
マイク

@マイク:うーんありがとう、私はそれを検討します。私はまだこれがpackage.json他のパッケージマネージャーで解決された制限だと思います。
14年

1
これは素晴らしい質問ですが、いくつかのツールを使用することであるため、トピックから外れていると思います。このような質問は、ツールがいくつかの開発プロセスにどのように統合されるかについて説明している場合にのみトピックに当てはまります。結局のところ、このサイトはソフトウェアエンジニアリングに関するものです。詳細については、ヘルプセンターをご覧ください。お読みください:ツールに関する質問はどこに行きますか?NPMなどの開発ツールの使用は、スタックオーバーフローに関するトピックになります。
アモン

回答:


9

相互依存モジュールは、あなたが探しているものであるか、またはに似た何かをするものがあります。

  • で、オプションの依存関係を宣言されていない自動でインストールを言います、package.jsonnpm installoptionalPeerDependencies
  • カスタムrequireについて知っているスタイルの機能optionalPeerDependenciesと正しいことをして、何も果たす必要なモジュールのクラス(例えばどちらことが判明していない場合に投げ/警告を含めredis、またmongo、またmysql、などがインストールされています)。
  • このモジュールの消費者が少なくとも1つのオプションのピアモジュールをインストールするという期待を文書化する

バリエーションの1つは、モジュールのコア機能がオプションの依存関係(プラグインパターンなど)なしで機能し、ピアの依存関係を満たすものが見つからない場合にエラー/警告がない場合です。

別の変形は、開発の依存対生産を考慮しながら、用のアナログ、すなわち上記のリストをやっているdependenciesdevDependencies

おそらく、オプションのモジュールが遅延的に要求されるようなオンデマンドの要求と組み合わせると、例えば:

exports = {
    Core : require('./core'),
    get redis(){ return require('./redis'); },
    get mongo(){ return require('./mongo'); }
}

私はしばらくこれを必要としませんでしたが、私が持っていた問題を解決すると思います。ありがとう!
imiric

2
ええ、私はそれがあなたがおそらくそれを見つけた、または先に進んだ月齢であると考えました。私は自分で答えを探している間にあなたの質問を見つけたので、これは主に後世のためでした。数年前に書いた自分からの答えを見つけるためだけに、私は何度も検索を行ってきました。したがって、この啓発された自己利益を考慮してください。また、回答が更新され、codependencyモジュールがNPMから蒸発した場合、および抜粋のないリンクが不適切なSO形式である場合に、モジュールが提供する内容が一般的に説明されます。
toolbear

9

プラグインなどの単純なオプションの依存関係が必要な場合、たとえばfooをインストールする場合はカラフルに実行しますが、インストールしない場合は問題なくグレーで表示されます。package.jsonでoptionalDependeciesを使用できます。

{
  "name": "watchit",
  "version": "1.2.3",
  "optionalDependencies": {
    "foo": "^2.0.0"
  }
}

そしてコードでは:

try {
  var foo = require('foo')
  var fooVersion = require('foo/package.json').version
} catch (er) {
  foo = null
}
if ( notGoodFooVersion(fooVersion) ) {
  foo = null
}

// .. then later in your program ..

if (foo) {
  foo.doFooThings()
}

package.jsonドキュメントから抽出。


1

私がやっていることはscripts、次のように、私の内部のpackage.jsonでインストールスクリプトを設定することです:

"install": "node ./my-tools/my-install.js",

npm install終了後すぐに実行されます。主に.envデフォルトでファイルを自動生成するために使用します。

my-install.jsこのスクリプトは、別のコマンドを実行してファイルを作成し、ユーザの入力を求めるので、あなたが言うことができる可能性があり、「Redisのか、モンゴをしたいですか?」:

const exec = require('child_process').exec;
const readline = require('readline');

// Insert "Ask question script" here
// using readline core module

if ( option == 'mongo' )
  exec('npm install mongoose');

if ( option == 'redis' )
  exec('npm install redis');

これは非常に迅速な回答です。ユーザー入力を適切に読み取るためのreadline、コマンドを実行して出力を処理するための子プロセスなどを確認してください。

また、インストールスクリプトは任意のもの(python、bashなど)にできることに注意してください。


2
ユーザー入力を要求すると、自動ビルドが台無しになります。npm installインストールスクリプト内で再度実行すると、意図しない動作がトリガーされる場合があります。このソリューションはお勧めしません。
ラムダ妖精

1

依存関係管理の最も難しい部分の1つは、簡単で比較的フェイルセーフな、高速で再現性のあるビルドを保証するためです。しかし、ユースケースがあり、確かに私にとってはあったと思います。だから私はあなたが求めていることを正確に行うためのパッケージを書きました。

私のパッケージはinstall-subsetであり、グローバルにインストールできますnpm install -g install-subset

https://www.npmjs.com/package/install-subset

最初に、package.jsonの名前付きインストールサブセットのホワイトリストとブラックリストを次のように作成します。

"subsets": {
    "build": {
        "whitelist": [
            "babel-cli",
            "dotenv"
        ]
    },
    "test": {
        "blacklist": [
            "eslint",
            "lint-rules",
            "prettier"
        ]
    }
}

次に、たとえば、 install-subset test

これにより、package.jsonが一時的に書き換えられ、ブラックリストに登録されたパッケージがインストールされずに復元されます。パッケージによっては、時間と帯域幅を大幅に節約できます。

また、糸で動作し、オープンソースであり、問​​題/ PRは大歓迎です。

多くの場合、私はこれをciサーバーで使用してビルド時間を短縮し、最新のReact Nativeプロジェクトでは、典型的な新規開発者のインストールを72秒から約20秒で完了しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.