it-swarm.com.de

Optionale Abhängigkeiten in npm?

Ich habe eine ähnliche Frage wie this , aber nicht ganz dieselbe.

Ich möchte, dass der Benutzer meiner App sie mit den Abhängigkeiten installiert, die für die Art und Weise erforderlich sind, wie er sie verwenden möchte. Wenn sie beispielsweise in MongoDB beibehalten möchten, werden nur Mongo-bezogene Bibliotheken installiert. Wenn sie jedoch in Redis beibehalten möchten, werden nur Redis-bezogene Bibliotheken installiert. Ich möchte nicht, dass sie Bibliotheken herunterladen und installieren, die sie nicht verwenden.

Ich weiß, dass ich das für Entwicklungszwecke mit devDependencies tun kann, aber das geht noch weiter. Wie die Antwort in der obigen Frage besagt, hängt dies enger mit Pythons setuptoolsextras_require Und Clojures leiningen Profilen zusammen. So etwas in npm? Ich bin wirklich der Meinung, dass devDependencies ein dev Profil einer vielseitigeren Art der Angabe von Abhängigkeiten sein sollte.

26
imiric

Das Codependenzmodul kann das sein, wonach Sie suchen, oder alles, was etwas Ähnliches tut wie:

  • deklarieren Sie optionale Abhängigkeiten in package.json dass nicht automatisch von npm install, sag optionalPeerDependencies
  • eine benutzerdefinierte Funktion im Stil von require, die sich mit optionalPeerDependencies auskennt und das Richtige tut, einschließlich Auslösen/Warnen, wenn nichts gefunden wird, das eine erforderliche Klasse von Modulen erfüllt (z. B. weder redis) , noch mongo, noch mysql usw. sind installiert).
  • dokumentieren Sie die Erwartung, dass Verbraucher dieses Moduls mindestens eines der optionalen Peer-Module installieren

Eine Variation wäre, wenn die Kernfunktionalität des Moduls ohne optionale Abhängigkeiten (z. B. Plugin-Muster) funktioniert, ohne Fehler/Warnung, wenn nichts gefunden wird, das eine Peer-Abhängigkeit erfüllt.

Eine andere Variante besteht darin, die obige Liste zu erstellen, während Produktions- und Entwicklungsabhängigkeiten berücksichtigt werden, d. H. Ein Analogon für dependencies und devDependencies.

Möglicherweise kombiniert mit einem bei Bedarf erforderlich , sodass optionale Module träge benötigt werden, z.

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

Wenn Sie einfache optionale Abhängigkeiten wie Plugins wünschen, z. Wenn Sie foo installieren, werden Sie es farbenfroh ausführen, aber wenn es nicht installiert ist, haben Sie kein Problem und sehen es grau. Dann können Sie optionalDependecies in package.json : verwenden.

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

Und im Code:

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()
}

Auszug aus der package.json Dokumentation .

10
PhoneixS

npm war wirklich nicht dafür ausgelegt, da einer der schwierigsten Teile des Abhängigkeitsmanagements darin besteht, schnelle, reproduzierbare Builds sicherzustellen, die einfach und relativ ausfallsicher sind. Aber ich glaube, es gibt einen Anwendungsfall, und es gab sicherlich einen für mich. Also habe ich ein Paket geschrieben, um genau das zu tun, wonach Sie fragen.

Mein Paket ist install-subset Und kann global mit npm install -g install-subset Installiert werden.

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

Zunächst erstellen Sie Whitelists und Blacklists für benannte Installations-Teilmengen in Ihrer package.json wie folgt:

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

Rufen Sie es dann zum Beispiel mit install-subset test

Dadurch wird Ihre package.json vorübergehend neu geschrieben, um die auf der schwarzen Liste stehenden Pakete nicht zu installieren, und anschließend wiederhergestellt, was je nach Paket viel Zeit und Bandbreite sparen kann.

Funktioniert auch mit Garn, ist Open Source und Probleme/PRs sind willkommen.

In vielen Fällen verwende ich dies auf unserem ci-Server, um die Erstellungszeit zu verkürzen, und bei unserem neuesten React Native-Projekt hat unsere typische Neuentwicklerinstallation von 72 Sekunden auf etwa 20 Sekunden gedauert.

2
tabrindle

Ich konfiguriere ein Installationsskript in meiner package.json in scripts wie folgt:

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

Es wird direkt nach Beendigung von npm install Ausgeführt. Ich benutze es hauptsächlich zum automatischen Generieren einer .env - Datei mit Standardwerten.

Das my-install.js - Skript kann verschiedene Befehle ausführen, Dateien erstellen und nach Benutzereingaben fragen. Dort können Sie also "Willst du Redis oder Mongo?" Sagen:

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');

Dies ist eine sehr schnelle Antwort. Schauen Sie sich readline zum korrekten Lesen von Benutzereingaben und ntergeordneter Prozess zum Ausführen von Befehlen und zum Verarbeiten von Ausgaben usw. an.

Beachten Sie auch, dass das Installationsskript beliebig sein kann (Python, Bash usw.).

1
aesede