Ist es möglich, Optionen an ES6-Importe zu übergeben?
Wie übersetzen Sie das:
var x = require('module')(someoptions);
zu ES6?
Ist es möglich, Optionen an ES6-Importe zu übergeben?
Wie übersetzen Sie das:
var x = require('module')(someoptions);
zu ES6?
Antworten:
Es gibt keine Möglichkeit, dies mit einer einzelnen import
Anweisung zu tun , sie erlaubt keine Aufrufe.
Sie würden es also nicht direkt aufrufen, aber Sie können im Grunde genau das tun, was commonjs mit Standardexporten macht:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
Wenn Sie alternativ einen Modullader verwenden, der monadische Versprechen unterstützt , können Sie möglicherweise so etwas tun
System.import('module').ap(someoptions).then(function(x) {
…
});
Mit dem neuen import
Operator könnte es werden
const promise = import('module').then(m => m(someoptions));
oder
const x = (await import('module'))(someoptions)
Sie möchten jedoch wahrscheinlich keinen dynamischen, sondern einen statischen Import.
import x from 'module' use someoptions;
Syntax
import {x, y} from 'module'
). Wie sollte dann die Syntax lauten, wenn ich mehrere Argumente übergeben möchte? Oder eine Reihe von Argumenten verbreiten? Es ist ein enger Anwendungsfall, und im Grunde versuchen Sie, eine andere Syntax für einen Funktionsaufruf hinzuzufügen, aber wir haben bereits Funktionsaufrufe, mit denen wir alle anderen Fälle behandeln können.
var session = require('express-session'); var RedisStore = require('connect-redis')(session);
nur gefragt, ob es eine einzeilige Lösung gibt. Ich kann mit der Aufteilung der RedisStore-Aufgabe in 2 Zeilen total überleben :)
import {default(someoptions) as x} from 'module'
in ES7 vorstellen , wenn es wirklich nötig ist.
session
/ connect-redis
Beispiel habe ich Syntax wie folgt worden vorstellen: import session from 'express-session'); import RedisStore(session) from 'connect-redis'
.
Hier ist meine Lösung mit ES6
Sehr im Einklang mit der Antwort von @ Bergi ist dies die "Vorlage", die ich beim Erstellen von Importen verwende, für die Parameter für class
Deklarationen übergeben werden müssen. Dies wird in einem isomorphen Framework verwendet, das ich schreibe. Es funktioniert also mit einem Transpiler im Browser und in node.js (ich verwende Babel
mit Webpack
):
./MyClass.js
export default (Param1, Param2) => class MyClass {
constructor(){
console.log( Param1 );
}
}
./main.js
import MyClassFactory from './MyClass.js';
let MyClass = MyClassFactory('foo', 'bar');
let myInstance = new MyClass();
Das Obige wird foo
in einer Konsole ausgegeben
BEARBEITEN
Für ein Beispiel aus der Praxis verwende ich dies, um einen Namespace für den Zugriff auf andere Klassen und Instanzen innerhalb eines Frameworks zu übergeben. Da wir einfach eine Funktion erstellen und das Objekt als Argument übergeben, können wir es mit unserer Klassendeklaration liko verwenden:
export default (UIFramework) => class MyView extends UIFramework.Type.View {
getModels() {
// ...
UIFramework.Models.getModelsForView( this._models );
// ...
}
}
Der Import ist etwas komplizierter und automagical
in meinem Fall ein komplettes Framework, aber im Wesentlichen passiert Folgendes:
// ...
getView( viewName ){
//...
const ViewFactory = require(viewFileLoc);
const View = ViewFactory(this);
return new View();
}
// ...
Ich hoffe das hilft!
MyView
bestimmte im Namespace des Frameworks verfügbare Elemente erweitert. Es ist zwar absolut möglich, es einfach als Parameter an die Klasse zu übergeben, es hängt jedoch auch davon ab, wann und wo die Klasse instanziiert wird. Die Portabilität ist dann betroffen. In der Praxis können diese Klassen an andere Frameworks übergeben werden, die sie möglicherweise anders instanziieren (z. B. benutzerdefinierte React-Komponenten). Wenn sich die Klasse außerhalb des Framework-Bereichs befindet, kann sie aufgrund dieser Methodik weiterhin auf das Framework zugreifen, wenn sie instanziiert wird.
Aufbauend auf der Antwort von @ Bergi , das Debug-Modul mit es6 zu verwenden, wäre dies die folgende
// original
var debug = require('debug')('http');
// ES6
import * as Debug from 'debug';
const debug = Debug('http');
// Use in your code as normal
debug('Hello World!');
Ich glaube, Sie können es6-Modullader verwenden. http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
m(youroptionshere)
? Ich nehme an, Sie könnten schreiben System.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})
... aber es ist nicht sehr klar.
Sie müssen nur diese 2 Zeilen hinzufügen.
import xModule from 'module';
const x = xModule('someOptions');
xModule
ist hier irreführend. Was Sie tatsächlich haben, ist import func from 'module'; func('someOptions');
.
Ich bin auf diesem Thread gelandet und habe nach etwas Ähnlichem gesucht und möchte zumindest für einige Fälle eine Art Lösung vorschlagen (siehe aber Bemerkung unten).
Anwendungsfall
Ich habe ein Modul, das unmittelbar nach dem Laden eine Instanziierungslogik ausführt. Ich mache nicht wie außerhalb des Moduls diese init Logik nennen (die die gleichen wie Anruf new SomeClass(p1, p2)
oder new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })
und gleichermaßen).
Ich mag es, dass diese Init-Logik einmal ausgeführt wird, eine Art singulärer Instanziierungsfluss, aber einmal in einem bestimmten parametrisierten Kontext.
Beispiel
service.js
hat in seinem sehr grundlegenden Umfang:
let context = null; // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));
Modul A macht:
import * as S from 'service.js'; // console has now "initialized in context root"
Modul B macht:
import * as S from 'service.js'; // console stays unchanged! module's script runs only once
So weit so gut: Der Service ist für beide Module verfügbar, wurde aber nur einmal initialisiert.
Problem
Wie kann man es als eine andere Instanz ausführen und sich erneut in einem anderen Kontext initiieren, beispielsweise in Modul C?
Lösung?
Ich denke darüber nach: Verwenden Sie Abfrageparameter. Im Service würden wir Folgendes hinzufügen:
let context = new URL(import.meta.url).searchParams.get('context');
Modul C würde tun:
import * as S from 'service.js?context=special';
Das Modul wird erneut importiert, die grundlegende Init-Logik wird ausgeführt und in der Konsole wird Folgendes angezeigt:
initialized in context special
Bemerkung: Ich würde mir raten, diesen Ansatz NICHT viel zu üben, sondern ihn als letzten Ausweg zu belassen. Warum? Mehr als einmal importiertes Modul ist eher eine Ausnahme als eine Regel, daher handelt es sich um ein etwas unerwartetes Verhalten, das als solches einen Verbraucher verwirren oder sogar seine eigenen "Singleton" -Paradigmen brechen kann, falls vorhanden.
Hier ist meine Sicht auf diese Frage am Beispiel des Debug-Moduls.
Auf der npm-Seite dieses Moduls haben Sie Folgendes:
var debug = require ('debug') ('http')
In der obigen Zeile wird eine Zeichenfolge an das zu importierende Modul übergeben, um sie zu erstellen. So würden Sie dasselbe in ES6 tun
{debug as Debug} aus 'debug' importieren const debug = Debug ('http');
Hoffe das hilft jemandem da draußen.
System.import(module)
, nicht sicher, ob dies Argumente zulässt oder nicht, jemand, der mehr über ES6 weiß, wahrscheinlich?