Est-il possible de transmettre des options aux importations ES6?
Comment traduisez-vous ceci:
var x = require('module')(someoptions);
à ES6?
Est-il possible de transmettre des options aux importations ES6?
Comment traduisez-vous ceci:
var x = require('module')(someoptions);
à ES6?
Réponses:
Il n'y a aucun moyen de faire cela avec une seule import
instruction, cela n'autorise pas les appels.
Donc, vous ne l'appelleriez pas directement, mais vous pouvez en gros faire exactement la même chose que commonjs avec les exportations par défaut:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
Alternativement, si vous utilisez un chargeur de module qui prend en charge les promesses monadiques , vous pourrez peut-être faire quelque chose comme
System.import('module').ap(someoptions).then(function(x) {
…
});
Avec le nouvel import
opérateur, il pourrait devenir
const promise = import('module').then(m => m(someoptions));
ou
const x = (await import('module'))(someoptions)
Cependant, vous ne voulez probablement pas une importation dynamique mais une importation statique.
import x from 'module' use someoptions;
de syntaxe
import {x, y} from 'module'
). Alors, quelle devrait être la syntaxe si je veux passer plusieurs arguments? Ou répandre un éventail d'arguments? C'est un cas d'utilisation restreint et en gros vous essayez d'ajouter une syntaxe différente pour un appel de fonction, mais nous avons déjà des appels de fonction qui nous permettent de traiter tous les autres cas.
var session = require('express-session'); var RedisStore = require('connect-redis')(session);
me suis rendu compte que je me demandais simplement s'il y avait une solution en une ligne. Je peux totalement survivre avec la répartition de la mission RedisStore en 2 lignes :)
import {default(someoptions) as x} from 'module'
dans ES7, s'il y a vraiment un besoin pour cela.
session
/ connect-redis
exemple, je suis imaginer la syntaxe comme ceci: import session from 'express-session'); import RedisStore(session) from 'connect-redis'
.
Voici ma solution utilisant ES6
Tout à fait conforme à la réponse de @ Bergi, c'est le "modèle" que j'utilise lors de la création d'importations qui nécessitent des paramètres passés pour les class
déclarations. Ceci est utilisé sur un framework isomorphe que j'écris, donc fonctionnera avec un transpilateur dans le navigateur et dans node.js (j'utilise Babel
avec 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();
Ce qui précède sortira foo
dans une console
ÉDITER
Pour un exemple du monde réel, j'utilise ceci pour passer dans un espace de noms pour accéder à d'autres classes et instances dans un cadre. Parce que nous créons simplement une fonction et que nous transmettons l'objet en tant qu'argument, nous pouvons l'utiliser avec notre déclaration de classe likeo:
export default (UIFramework) => class MyView extends UIFramework.Type.View {
getModels() {
// ...
UIFramework.Models.getModelsForView( this._models );
// ...
}
}
L'importation est un peu plus compliquée et automagical
dans mon cas étant donné que c'est un framework entier, mais c'est essentiellement ce qui se passe:
// ...
getView( viewName ){
//...
const ViewFactory = require(viewFileLoc);
const View = ViewFactory(this);
return new View();
}
// ...
J'espère que ça aide!
MyView
étend certains éléments disponibles dans l'espace de noms du framework. Bien qu'il soit absolument possible de le transmettre simplement en tant que paramètre à la classe, cela dépend également du moment et de l'endroit où la classe est instanciée; la portabilité est alors affectée. En pratique, ces classes peuvent être transférées à d'autres frameworks qui peuvent les instancier différemment (par exemple, des composants React personnalisés). Lorsque la classe se trouve hors de la portée du framework, elle peut toujours conserver l'accès au framework lorsqu'elle est instanciée en raison de cette méthodologie.
S'appuyant sur la réponse de @ Bergi pour utiliser le module de débogage en utilisant es6 serait le suivant
// 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!');
Je pense que vous pouvez utiliser des chargeurs de module es6. http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
m(youroptionshere)
finit le résultat ? Je suppose que vous pourriez écrire System.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})
... mais ce n'est pas très clair.
Il vous suffit d'ajouter ces 2 lignes.
import xModule from 'module';
const x = xModule('someOptions');
xModule
est trompeur ici. Ce que vous avez réellement est import func from 'module'; func('someOptions');
.
J'ai atterri sur ce fil à la recherche d'un peu similaire et j'aimerais proposer une sorte de solution, au moins pour certains cas (mais voir la remarque ci-dessous).
Cas d'utilisation
J'ai un module, qui exécute une logique d'instanciation immédiatement lors du chargement. Je n'aime pas appeler cette logique d'initialisation en dehors du module (ce qui revient à appeler new SomeClass(p1, p2)
ounew ((p1, p2) => class SomeClass { ... p1 ... p2 ... })
and alike).
J'aime le fait que cette logique init s'exécute une fois, une sorte de flux d'instanciation singulier, mais une fois par contexte paramétré spécifique.
Exemple
service.js
a à sa portée très basique:
let context = null; // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));
Le module A fait:
import * as S from 'service.js'; // console has now "initialized in context root"
Le module B fait:
import * as S from 'service.js'; // console stays unchanged! module's script runs only once
Jusqu'ici tout va bien: le service est disponible pour les deux modules mais n'a été initialisé qu'une seule fois.
Problème
Comment le faire fonctionner comme une autre instance et l'initier à nouveau dans un autre contexte, par exemple dans le module C?
Solution?
C'est ce à quoi je pense: utiliser des paramètres de requête. Dans le service, nous ajouterions ce qui suit:
let context = new URL(import.meta.url).searchParams.get('context');
Le module C ferait:
import * as S from 'service.js?context=special';
le module sera réimporté, sa logique d'initialisation de base s'exécutera et nous verrons dans la console:
initialized in context special
Remarque: je conseillerais moi-même de NE PAS pratiquer beaucoup cette approche, mais de la laisser en dernier recours. Pourquoi? Le module importé plus d'une fois est plus une exception qu'une règle, il s'agit donc d'un comportement quelque peu inattendu et, en tant que tel, peut confondre un consommateur ou même casser ses propres paradigmes «singleton», le cas échéant.
Voici mon point de vue sur cette question en utilisant le module de débogage comme exemple;
Sur la page npm de ce module, vous avez ceci:
var debug = require ('debug') ('http')
Dans la ligne ci-dessus, une chaîne est passée au module importé, à construire. Voici comment vous feriez de même dans ES6
import {debug as Debug} depuis 'debug' const debug = Debug ('http');
J'espère que cela aide quelqu'un là-bas.
System.import(module)
, je ne sais pas si cela permet des arguments ou non, quelqu'un qui en sait plus sur ES6 le fait probablement?