È possibile passare le opzioni alle importazioni ES6?
Come traduci questo:
var x = require('module')(someoptions);
a ES6?
È possibile passare le opzioni alle importazioni ES6?
Come traduci questo:
var x = require('module')(someoptions);
a ES6?
Risposte:
Non c'è modo di farlo con una singola import
istruzione, non consente invocazioni.
Quindi non lo chiameresti direttamente, ma puoi praticamente fare lo stesso come fanno i commonjs con le esportazioni predefinite:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
In alternativa, se usi un caricatore di moduli che supporta promesse monadiche , potresti essere in grado di fare qualcosa del genere
System.import('module').ap(someoptions).then(function(x) {
…
});
Con il nuovo import
operatore potrebbe diventare
const promise = import('module').then(m => m(someoptions));
o
const x = (await import('module'))(someoptions)
tuttavia probabilmente non vuoi un'importazione dinamica ma statica.
import x from 'module' use someoptions;
specie di sintassi
import {x, y} from 'module'
.). Quindi quale dovrebbe essere la sintassi se voglio passare più argomenti? O diffondere una serie di argomenti? È un caso d'uso ristretto e sostanzialmente stai cercando di aggiungere una sintassi diversa per una chiamata di funzione, ma abbiamo già chiamate di funzione che ci consentono di affrontare tutti gli altri casi.
var session = require('express-session'); var RedisStore = require('connect-redis')(session);
mi chiedevo solo se esistesse una soluzione a una riga. Riesco a sopravvivere totalmente dividendo il compito del RedisStore in 2 righe :)
import {default(someoptions) as x} from 'module'
a ES7, se ce n'è davvero bisogno.
session
/ connect-redis
esempio, mi è stato immaginando sintassi simile a questo: import session from 'express-session'); import RedisStore(session) from 'connect-redis'
.
Ecco la mia soluzione con ES6
In linea con la risposta di @ Bergi, questo è il "modello" che utilizzo quando creo importazioni che richiedono parametri passati per le class
dichiarazioni. Questo è usato su un framework isomorfo che sto scrivendo, quindi funzionerà con un transpiler nel browser e in node.js (che uso Babel
con 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();
Quanto sopra verrà emesso foo
in una console
MODIFICARE
Per un esempio del mondo reale, sto usando questo per passare in uno spazio dei nomi per accedere ad altre classi e istanze all'interno di un framework. Poiché stiamo semplicemente creando una funzione e passando l'oggetto come argomento, possiamo usarlo con la nostra dichiarazione di classe likeo:
export default (UIFramework) => class MyView extends UIFramework.Type.View {
getModels() {
// ...
UIFramework.Models.getModelsForView( this._models );
// ...
}
}
L'importazione è un po 'più complicata e automagical
nel mio caso dato che si tratta di un intero framework, ma essenzialmente questo è ciò che sta accadendo:
// ...
getView( viewName ){
//...
const ViewFactory = require(viewFileLoc);
const View = ViewFactory(this);
return new View();
}
// ...
Spero che aiuti!
MyView
estende alcuni elementi disponibili nello spazio dei nomi del framework. Sebbene sia assolutamente possibile passarlo semplicemente come parametro alla classe, dipende anche da quando e dove la classe viene istanziata; la portabilità è quindi interessata. In pratica, queste classi possono essere consegnate ad altri framework che possono istanziarle in modo diverso (ad es. Componenti React personalizzati). Quando la classe si trova al di fuori dell'ambito del framework, può comunque mantenere l'accesso al framework quando viene istanziata a causa di questa metodologia.
Basandosi sulla risposta di @ Bergi per usare il modulo di debug usando es6 sarebbe il seguente
// 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!');
Credo che tu possa usare i caricatori di moduli es6. http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
m(youroptionshere)
? Suppongo che potresti scrivere System.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})
... ma non è molto chiaro.
Devi solo aggiungere queste 2 righe.
import xModule from 'module';
const x = xModule('someOptions');
xModule
è fuorviante qui. Quello che hai effettivamente è import func from 'module'; func('someOptions');
.
Sono atterrato su questa discussione cercando qualcosa di simile e vorrei proporre una sorta di soluzione, almeno per alcuni casi (ma vedi Nota sotto).
Caso d'uso
Ho un modulo che esegue immediatamente una logica di istanza al momento del caricamento. Faccio non piace chiamare questa logica init all'esterno del modulo (che è la stessa chiamata new SomeClass(p1, p2)
o new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })
e simili).
Mi piace il fatto che questa logica di init verrà eseguita una volta, una specie di flusso di istanza singolare, ma una volta per un contesto parametrico specifico.
Esempio
service.js
ha al suo scopo molto basilare:
let context = null; // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));
Il modulo A fa:
import * as S from 'service.js'; // console has now "initialized in context root"
Il modulo B fa:
import * as S from 'service.js'; // console stays unchanged! module's script runs only once
Fin qui tutto bene: il servizio è disponibile per entrambi i moduli ma è stato inizializzato solo una volta.
Problema
Come farlo funzionare come un'altra istanza e iniziarsi di nuovo in un altro contesto, diciamo nel Modulo C?
Soluzione?
Questo è ciò a cui sto pensando: usa i parametri della query. Nel servizio aggiungeremo quanto segue:
let context = new URL(import.meta.url).searchParams.get('context');
Il modulo C farebbe:
import * as S from 'service.js?context=special';
il modulo verrà reimportato, verrà eseguita la logica di inizializzazione di base e vedremo nella console:
initialized in context special
Nota: io stesso consiglierei di NON praticare molto questo approccio, ma di lasciarlo come ultima risorsa. Perché? Il modulo importato più di una volta è più un'eccezione che una regola, quindi è un comportamento inaspettato e come tale può confondere un consumatore o addirittura rompere i suoi paradigmi "singleton", se presenti.
Ecco la mia opinione su questa domanda usando il modulo di debug come esempio;
Nella pagina npm di questo modulo, hai questo:
var debug = require ('debug') ('http')
Nella riga sopra, una stringa viene passata al modulo che viene importato, per la costruzione. Ecco come faresti lo stesso in ES6
import {debug as Debug} da 'debug' const debug = Debug ('http');
Spero che questo aiuti qualcuno là fuori.
System.import(module)
, non sei sicuro che ciò permetta o meno argomenti, probabilmente qualcuno che sa di più su ES6 lo fa?