Можно ли передать опции для импорта ES6?
Как вы переводите это:
var x = require('module')(someoptions);
к ES6?
Можно ли передать опции для импорта ES6?
Как вы переводите это:
var x = require('module')(someoptions);
к ES6?
Ответы:
Нет способа сделать это с помощью одного import
оператора, он не допускает вызовов.
Так что вы бы не назвали это напрямую, но вы можете сделать то же самое, что и обычные экспорты по умолчанию:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
Кроме того, если вы используете загрузчик модулей, который поддерживает монадические обещания, вы можете сделать что-то вроде
System.import('module').ap(someoptions).then(function(x) {
…
});
С новым import
оператором это может стать
const promise = import('module').then(m => m(someoptions));
или
const x = (await import('module'))(someoptions)
однако вы, вероятно, не хотите динамический импорт, но статический.
import x from 'module' use someoptions;
синтаксиса
import {x, y} from 'module'
). Тогда какой должен быть синтаксис, если я хочу передать несколько аргументов? Или распространять массив аргументов? Это узкий вариант использования, и в основном вы пытаетесь добавить другой синтаксис для вызова функции, но у нас уже есть вызовы функций, которые позволяют нам иметь дело со всеми другими случаями.
var session = require('express-session'); var RedisStore = require('connect-redis')(session);
вопросом, было ли решение в одну строку. Я могу полностью выжить, разделив задание RedisStore на 2 строки :)
import {default(someoptions) as x} from 'module'
на ES7, если в этом действительно есть необходимость.
session
/ connect-redis
например, я себе синтаксис вроде этого: import session from 'express-session'); import RedisStore(session) from 'connect-redis'
.
Вот мое решение с использованием ES6
В значительной степени совпадает с ответом @ Bergi. Это «шаблон», который я использую при создании импорта, для которого необходимо передать параметры для class
объявлений. Это используется в изоморфной среде, которую я пишу, поэтому будет работать с транспилером в браузере и в node.js (я использую Babel
с 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();
Выше будет выводить foo
в консоли
РЕДАКТИРОВАТЬ
Для примера из реального мира я использую это для передачи пространства имен для доступа к другим классам и экземплярам в рамках. Поскольку мы просто создаем функцию и передаем объект в качестве аргумента, мы можем использовать его с нашим объявлением класса likeso:
export default (UIFramework) => class MyView extends UIFramework.Type.View {
getModels() {
// ...
UIFramework.Models.getModelsForView( this._models );
// ...
}
}
Импорт немного сложнее и automagical
в моем случае, учитывая, что это целая структура, но по сути это то, что происходит:
// ...
getView( viewName ){
//...
const ViewFactory = require(viewFileLoc);
const View = ViewFactory(this);
return new View();
}
// ...
Надеюсь, это поможет!
MyView
расширяет некоторые элементы, доступные в пространстве имен платформы. Хотя это абсолютно возможно просто передать в качестве параметра классу, это также зависит от того, когда и где создается экземпляр класса; переносимость тогда затронута. На практике эти классы могут быть переданы другим средам, которые могут создавать их экземпляры по-разному (например, пользовательские компоненты React). Когда класс оказывается вне рамок фреймворка, он все равно может поддерживать доступ к фреймворку при создании экземпляра благодаря этой методологии.
Основываясь на ответе @ Bergi об использовании модуля отладки с использованием es6, будет следующий
// 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!');
Я считаю, что вы можете использовать загрузчики модулей es6. http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
m(youroptionshere)
итоге? Я полагаю, вы могли бы написать System.import('lib/math').then(m => m(options)).then(module => { /* code using module here */})
... но это не очень понятно.
Вам просто нужно добавить эти 2 строки.
import xModule from 'module';
const x = xModule('someOptions');
xModule
вводит в заблуждение здесь. То , что вы на самом деле есть это import func from 'module'; func('someOptions');
.
Я попал в эту ветку в поисках чего-то похожего и хотел бы предложить своего рода решение, по крайней мере, в некоторых случаях (но см. Замечание ниже).
Случай использования
У меня есть модуль, который запускает некоторую логику реализации сразу после загрузки. Я не люблю вызывать эту логику инициализации вне модуля (которая такая же, как call new SomeClass(p1, p2)
или new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })
и так).
Мне нравится, что эта логика инициализации будет запущена один раз, что-то вроде единственного потока реализации, но один раз для некоторого конкретного параметризованного контекста.
пример
service.js
имеет в своей основной области:
let context = null; // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));
Модуль А выполняет:
import * as S from 'service.js'; // console has now "initialized in context root"
Модуль B делает:
import * as S from 'service.js'; // console stays unchanged! module's script runs only once
Пока все хорошо: сервис доступен для обоих модулей, но инициализирован только один раз.
проблема
Как заставить его работать как другой экземпляр и снова инициировать себя в другом контексте, скажем, в модуле C?
Решение?
Вот о чем я думаю: используйте параметры запроса. В сервис добавили бы следующее:
let context = new URL(import.meta.url).searchParams.get('context');
Модуль C будет делать:
import * as S from 'service.js?context=special';
модуль будет повторно импортирован, его основная логика инициализации будет запущена, и мы увидим в консоли:
initialized in context special
Замечание: Я бы сам посоветовал НЕ практиковать этот подход, но оставлю его как последнее средство. Зачем? Модуль, импортированный более одного раза, является скорее исключением, чем правилом, так что это несколько неожиданное поведение и, как таковое, может сбить с толку потребителей или даже нарушить его собственные «единичные» парадигмы, если таковые имеются.
Вот мой взгляд на этот вопрос на примере модуля отладки;
На странице модуля npm у вас есть это:
var debug = require ('debug') ('http')
В строке выше строка передается в импортируемый модуль для создания. Вот как бы вы сделали то же самое в ES6
import {debug as Debug} из 'debug' const debug = Debug ('http');
Надеюсь, это поможет кому-то там.
System.import(module)
, не уверен, что это позволяет аргументы или нет, кто-то, кто знает больше о ES6, вероятно, делает?