¿Es posible pasar opciones a las importaciones ES6?
Cómo traduces esto:
var x = require('module')(someoptions);
a ES6?
¿Es posible pasar opciones a las importaciones ES6?
Cómo traduces esto:
var x = require('module')(someoptions);
a ES6?
Respuestas:
No hay forma de hacer esto con una sola import
declaración, no permite invocaciones.
Por lo tanto, no lo llamaría directamente, pero básicamente puede hacer lo mismo que commonjs hace con las exportaciones predeterminadas:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
Alternativamente, si usa un cargador de módulos que admite promesas monádicas , podría hacer algo como
System.import('module').ap(someoptions).then(function(x) {
…
});
Con el nuevo import
operador podría convertirse
const promise = import('module').then(m => m(someoptions));
o
const x = (await import('module'))(someoptions)
sin embargo, probablemente no desee una importación dinámica sino estática.
import x from 'module' use someoptions;
un poco de sintaxis
import {x, y} from 'module'
). Entonces, ¿cuál debería ser la sintaxis si quiero pasar varios argumentos? O difundir una serie de argumentos? Es un caso de uso limitado y básicamente está tratando de agregar una sintaxis diferente para una llamada de función, pero ya tenemos llamadas de función que nos permiten ocuparnos de todos los demás casos.
var session = require('express-session'); var RedisStore = require('connect-redis')(session);
me preguntaba si había una solución de una línea. Puedo sobrevivir totalmente con dividir la asignación de RedisStore en 2 líneas :)
import {default(someoptions) as x} from 'module'
en ES7, si realmente es necesario.
session
/ connect-redis
ejemplo, he estado imaginando sintaxis como esta: import session from 'express-session'); import RedisStore(session) from 'connect-redis'
.
Aquí está mi solución usando ES6
Muy en línea con la respuesta de @ Bergi, esta es la "plantilla" que uso cuando creo importaciones que necesitan pasar parámetros para las class
declaraciones. Esto se usa en un marco isomorfo que estoy escribiendo, por lo que funcionará con un transpiler en el navegador y en node.js (lo 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();
Lo anterior saldrá foo
en una consola
EDITAR
Para un ejemplo del mundo real, estoy usando esto para pasar en un espacio de nombres para acceder a otras clases e instancias dentro de un marco. Debido a que simplemente estamos creando una función y pasando el objeto como argumento, podemos usarlo con nuestra declaración de clase likeso:
export default (UIFramework) => class MyView extends UIFramework.Type.View {
getModels() {
// ...
UIFramework.Models.getModelsForView( this._models );
// ...
}
}
La importación es un poco más complicada y automagical
en mi caso dado que es un marco completo, pero esencialmente esto es lo que está sucediendo:
// ...
getView( viewName ){
//...
const ViewFactory = require(viewFileLoc);
const View = ViewFactory(this);
return new View();
}
// ...
¡Espero que esto ayude!
MyView
extiende ciertos elementos disponibles en el espacio de nombres del marco. Si bien es absolutamente posible pasarlo simplemente como un parámetro a la clase, también depende de cuándo y dónde se instancia la clase; La portabilidad se ve afectada. En la práctica, estas clases se pueden entregar a otros marcos que pueden instanciarlas de manera diferente (por ejemplo, componentes de React personalizados). Cuando la clase se encuentra fuera del alcance del marco, aún puede mantener el acceso al marco cuando se crea una instancia debido a esta metodología.
A partir de la respuesta de @ Bergi para usar el módulo de depuración usando es6, sería lo siguiente
// 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!');
Creo que puedes usar cargadores de módulos es6. http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
m(youroptionshere)
? Supongo que podrías escribir System.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})
... pero no está muy claro.
Solo necesita agregar estas 2 líneas.
import xModule from 'module';
const x = xModule('someOptions');
xModule
Es engañoso aquí. Lo que realmente tienes es import func from 'module'; func('someOptions');
.
Llegué a este hilo buscando algo similar y me gustaría proponer un tipo de solución, al menos para algunos casos (pero vea el Comentario a continuación).
Caso de uso
Tengo un módulo, que ejecuta una lógica de instanciación inmediatamente después de la carga. No me gusta llamar a esta lógica de inicio fuera del módulo (que es lo mismo que call new SomeClass(p1, p2)
o new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })
similar).
Me gusta que esta lógica de inicio se ejecute una vez, una especie de flujo de instanciación singular, pero una vez por algún contexto parametrizado específico.
Ejemplo
service.js
tiene en su alcance muy básico:
let context = null; // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));
El módulo A hace:
import * as S from 'service.js'; // console has now "initialized in context root"
El módulo B hace:
import * as S from 'service.js'; // console stays unchanged! module's script runs only once
Hasta ahora todo bien: el servicio está disponible para ambos módulos, pero se inicializó solo una vez.
Problema
¿Cómo hacer que se ejecute como otra instancia y se inicie una vez más en otro contexto, por ejemplo, en el Módulo C?
¿Solución?
Esto es lo que estoy pensando: usar parámetros de consulta. En el servicio agregaríamos lo siguiente:
let context = new URL(import.meta.url).searchParams.get('context');
El módulo C haría:
import * as S from 'service.js?context=special';
el módulo se volverá a importar, se ejecutará su lógica de inicio básica y veremos en la consola:
initialized in context special
Observación: yo mismo aconsejaría NO practicar mucho este enfoque, pero dejarlo como último recurso. ¿Por qué? El módulo importado más de una vez es más una excepción que una regla, por lo que es un comportamiento algo inesperado y, como tal, puede confundir a los consumidores o incluso romper sus propios paradigmas 'singleton', si los hay.
Aquí está mi opinión sobre esta pregunta usando el módulo de depuración como ejemplo;
En la página npm de este módulo, tiene esto:
var debug = require ('debug') ('http')
En la línea anterior, se pasa una cadena al módulo que se importa, para construir. Así es como harías lo mismo en ES6
import {debug as Debug} de 'debug' const debug = Debug ('http');
Espero que esto ayude a alguien por ahí.
System.import(module)
hacerlo , hay una API de carga de módulos, o al menos hubo alguna vez, que usó algo como , no estoy seguro de si eso permite argumentos o no, ¿alguien que sabe más sobre ES6 probablemente sí?