2016-06-02 2 views
6

Client-seitiger Stub-I Pfade zu Module mit SystemJS aus, wie dieseKarte Pfade für Knoten-Module, für Unit-Tests

var systemJsConfig = { 
    baseURL: "./", 
    defaultJSExtensions: true, 
    map: { 
     'root-components': 'applicationRoot/rootComponents' 
    } 
}; 

und so würde require('root-components/foo'); zu applicationRoot/rootComponents/foo kartieren.

Das Problem ist, wenn ich ein Modul mit require('root-components/foo'); in Mocha ausführen, Knoten hat keine Ahnung, was dieser Pfad bedeutet. Gibt es einen vernünftigen Weg, um diese Pfadzuordnung in Node zu erreichen?

Ist Proxyquire dazu in der Lage? Ich las ihre Dokumente durch, fand aber nichts, was darauf hinwies.

Dies ist nur für Komponententests, so bin ich glücklich mit jeder Lösung mit jeder Art von Party-Dienstprogramm.

+1

Haben Sie diese Diskussion gesehen? https://gist.github.com/branneman/8048520. Ich glaube, es gibt ein paar Lösungen/Hacks, die für das, was Sie versuchen, relevant sind. – user2263572

+1

Warum würden Sie einen anderen Modullademechanismus für Tests verwenden? Warum nicht SystemJs auch dort verwenden? –

+0

SystemJS ist zum Laden von Dingen in den Browser. Mocha läuft im Knoten. –

Antwort

5

gefunden werden Wenn Ihre einzige Anforderung so einfach ist, können Sie eine Dienstprogrammfunktion, die require überschreibt.

Die neue erfordern gilt eine Abbildung auf den Pfad Argument, sucht für ein Modul in dem neuen Pfad, und Sie können für die Module optional Rückfall, die in dem abgebildeten Pfad nicht existieren. Der Code sollte so aussehen:

const oldRequire = require; 
require = (path) => { 
    try { 
     const mapped = oldRequire(path.replace('root-components/foo', 'applicationRoot/rootComponents/foo')); 
     if (!mapped) { 
      throw new Error('module not found in mapped directory'); 
     } 
     console.log('module resolved with mapping', path); 
     return mapped; 
    } catch (e) { 
     console.log('using old require without mapped path', path); 
     return oldRequire(path); 
    } 
}; 
+0

Ich denke das ist es! Danke - nicht sicher, warum ich nicht daran gedacht habe :) –

1

Sie könnten eine Menge verschiedener Möglichkeiten tun Modul Aliasing as described in this gist, aber der einfachere Weg ist nur der Ausgangswurzelpfad zu setzen mit NODE_PATH, und gehen von dort aus:

Hier ist, wie es mit der NODE_PATH Umgebungsvariable sieht :

NODE_PATH=./src node src/server/index.js

dann in all Ihren Dateien, unabhängig davon, wo sie in der Hierarchie sind, wird aus dem ./src Verzeichnis lösen. Dies eliminiert die Notwendigkeit von Aliasnamen, wie Sie es beschreiben, aber mir ist klar, dass in Ihrem Fall viele Dateien verschoben/umbenannt werden müssen.

Beispiel: require('root-components/foo'); =>./src/root-components/foo.js

+1

Vielen Dank für die guten Informationen - es sieht aus wie die Muster in diesem Kern sind versuchen, ein anderes Problem zu lösen, nämlich Dinge wie "../../../../ foo/bar" zu eliminieren. Clientseitige JavaScript Loader bieten eine einfache Pfadauflösung. Ich versuche nur zu sehen, ob es einen Hack gibt, damit diese benutzerdefinierten Pfade in Node für Unit-Tests funktionieren. Das Problem für mich mit einem globalen NODE_PATH Einstellung ist, dass es * alles * geladen beeinflussen wird, nicht nur die wenige Dinge in 'root-components' sitzen –

1

Option 1 - Ändern NODE_PATH (nicht empfohlen):

Modify NODE_PATH umfassen die Modulpfade in der Schale vor dem Start node.js.

exports NODE_PATH=./path/to/module:$NODE_PATH 

Dies ist keine gute Option, weil es einen Pre-Launch-Schritt erfordert, und - da die NODE_PATH enthält viele Wege - es ist nicht immer klar, wo das Modul aus geladen wird, und es gibt die Möglichkeit, Namenskollisionen .

Option 2 - Schieben Sie das Modul in einen externen Repo

Lassen Sie uns sagen Sie die Komponenten in einem separaten ‚rootcomponents‘ auf GitHub Profil verfügbar Repo bewegen.

Dann können Sie es installieren direkt über:

npm install --save github:arackaf/rootcomponents 

Dann sollten Sie in der Lage sein, das Projekt Quelle zu einem System.js alias abzubilden.

var systemJsConfig = { 
    baseURL: "./", 
    defaultJSExtensions: true, 
    map: { 
     'root-components': 'github:arackaf/rootcomponents' 
    } 
}; 

Von dort sollte es, wie Sie erwartet:

require('root-components/foo'); 

Option 3 - Laden Sie das Modul über relative Pfad:

Die config.map Option ist nur für Aliase externe Abhängigkeiten abzubilden .

Eine einfache Alternative besteht darin, einen relativen Pfad anzugeben. Verwandte Pfade basieren auf der baseURL.

Zum Beispiel, wenn Sie Last sind versuchen:

src/rootComponents/foo.js 

Das wäre erforderlich:

require('./src/rootComponents/foo') 

Hinweis: Dies alles setzt voraus, dass die require() Aussagen folgendes System .js Muster/Regeln.

Eine andere mögliche Option ist die Bereitstellung einer System.paths[] Option, die einen Alias ​​für einen lokalen Pfad erstellt. Ich kann nicht überprüfen, wie/ob das funktioniert (dh ich habe es noch nie versucht), aber die Besonderheiten können here

+0

Ja, leider die Lösung sein können, verwenden, nur nicht' map'ed Pfade in jedem Modul, das ich in Mocha verwenden muss. * Seufz * –

+0

@AdamRackis Vielleicht Kasse 'System.config.packages' https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#packages. Offenbar können Sie commonjs als Modulformat angeben und lokale Pfade zu Aliasen zuordnen. –

+0

Sicher, aber die Abbildung lokale Pfade zu Aliase ist die Wurzel meines Problems - Knoten nicht diese Aliase nicht verstehen und werfen Fehler, wenn ich versuche, diese Module durch Mokka zu laufen. –

Verwandte Themen