web-dev-qa-db-ja.com

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

this と同様の質問がありますが、まったく同じではありません。

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

私はdevDependenciesを使用して開発目的でそれを実行できることを知っていますが、これはそれよりもはるかに遠くに行きます。上記の質問の答えが言うように、これはPythonのsetuptoolsextras_requireおよびClojureのleiningenプロファイルとより密接に関連しています。 npmではそのようなものはありますか? devDependenciesは、依存関係を指定するためのより用途の広い方法のdevプロファイルである必要があると本当に感じています。

26
imiric

codependency module は、あなたが探しているものか、次のような何かをするものです:

  • _package.json_でオプションの依存関係を宣言しますare n't _npm install_によって自動的にインストールされます。たとえば、optionalPeerDependencies
  • requireを認識し、適切な処理を行うカスタムoptionalPeerDependenciesスタイルの関数。必要なモジュールのクラスを満たすものが見つからない場合のスロー/警告(例:redismongomysqlなどもインストールされていません)。
  • このモジュールの利用者が少なくとも1つのオプションのピアモジュールをインストールするという期待を文書化する

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

別のバリエーションは、プロダクションと開発の依存関係を考慮しながら上記のリストを実行することです。つまり、dependenciesdevDependenciesの類似物です。

おそらく on-demand require と組み合わせると、オプションのモジュールが遅延して要求されるようになります。例:

_exports = {
    Core : require('./core'),
    get redis(){ return require('./redis'); },
    get mongo(){ return require('./mongo'); }
}
_
10
toolbear

プラグインのような単純なオプションの依存関係が必要な場合。 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のドキュメント から抽出。

10
PhoneixS

依存関係管理の最も困難な部分の1つは、簡単で比較的フェイルセーフである高速で再現可能なビルドを保証することであるため、npmは実際にはこれのために設計されていません。しかし、私にはユースケースがあると私は信じており、確かに私にはありました。だから私はあなたが求めていることを正確に行うためのパッケージを書きました。

私のパッケージは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ネイティブプロジェクトでは、通常の新規開発者のインストールに72秒から約20秒かかりました。

2
tabrindle

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

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

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

my-install.jsスクリプトは、さまざまなコマンドを実行したり、ファイルを作成したり、ユーザー入力を要求したりできるので、「RedisまたはMongo?

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 を、コマンドの実行や出力の処理などには child process を確認してください。

また、インストールスクリプトは任意のものにすることができます(python、bashなど)。

1
aesede