是否可以将选项传递给ES6导入?
您如何翻译此:
var x = require('module')(someoptions);
到ES6?
是否可以将选项传递给ES6导入?
您如何翻译此:
var x = require('module')(someoptions);
到ES6?
Answers:
用单个import
语句无法做到这一点,它不允许调用。
因此,您不会直接调用它,但是基本上可以执行与commonjs默认导出相同的操作:
// 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分配为两行,我可以完全生存下来:)
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
在控制台中输出
编辑
对于一个真实的示例,我正在使用它来传递名称空间,以访问框架中的其他类和实例。因为我们只是创建一个函数并将对象作为参数传递,所以可以将其与类声明一起使用,如下所示:
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组件)。当类发现自己在框架范围之外时,由于这种方法,它在实例化时仍可以保持对框架的访问。
我相信您可以使用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 */})
...但是还不太清楚。
您只需要添加这两行。
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'));
模块A:
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中执行的操作
从'debug'导入{debug as Debug} const debug = Debug('http');
希望这可以帮助某人。
System.import(module)
,不确定是否允许自变量,对ES6了解更多的人可能呢?