是否可以将选项传递给 ES6 导入?
这句话怎么翻译:
var x = require('module')(someoptions);
到 ES6?
无法使用单个
import
语句来执行此操作,它不允许调用。
所以你不会直接调用它,但你基本上可以做与 commonjs 使用默认导出相同的事情:
// module.js
export default function(options) {
return {
// actual module
}
}
// main.js
import m from 'module';
var x = m(someoptions);
或者,如果您使用支持 monadic 承诺的模块加载器,您也许可以执行类似的操作
System.import('module').ap(someoptions).then(function(x) {
…
});
import
运算符,它可能会变成
const promise = import('module').then(m => m.default(someoptions));
或
const x = (await import('module')).default(someoptions)
但是您可能不想要动态导入而是静态导入。
这是我使用 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();
}
// ...
我希望这有帮助!
我已经登陆这个线程寻找一些类似的解决方案,并想提出一种解决方案,至少对于某些情况(但请参阅下面的备注)。
用例
我有一个模块,它在加载后立即运行一些实例化逻辑。我确实不喜欢在模块外部调用此初始化逻辑(与调用
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
备注:我自己建议不要过多练习这种方法,而是将其作为最后的手段。为什么?多次导入的模块更多的是例外而不是规则,因此这在某种程度上是意外的行为,因此可能会让消费者感到困惑,甚至打破它自己的“单例”范例(如果有的话)。
我相信你可以使用es6模块加载器。 http://babeljs.io/docs/learn-es6/
System.import("lib/math").then(function(m) {
m(youroptionshere);
});
您只需添加这两行即可。
import xModule from 'module';
const x = xModule('someOptions');
这是我对这个问题的看法,以调试模块为例;
在此模块的 npm 页面上,您可以看到:
var debug = require('debug')('http')
在上面的行中,一个字符串被传递给导入的模块以进行构造。这是在 ES6 中如何做同样的事情
import { debug as Debug } from 'debug'
const debug = Debug('http');
希望这对那里的人有帮助。
在尝试将一些 CJS (
require()
) 代码转换为 ESM (import
) 时,我遇到了类似的语法问题 - 这是我需要导入 Redis 时有效的方法:
CJS
const RedisStore = require('connect-redis')(session);
ESM 等效
import connectRedis from 'connect-redis';
const RedisStore = connectRedis(session);
您可以直接在模块说明符中传递参数:
import * as Lib from "./lib?foo=bar";
cf:https://flaming.codes/en/posts/es6-import-with-parameters