将选项传递给ES6模块导入

时间:2015-04-28 15:42:04

标签: javascript module ecmascript-6 es6-modules

是否可以将选项传递给ES6导入?

你如何翻译:

var x = require('module')(someoptions);

到ES6?

7 个答案:

答案 0 :(得分:89)

使用单个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 operator可能会变成

const promise = import('module').then(m => m(someoptions));

const x = (await import('module'))(someoptions)

然而,您可能不想要动态导入,但需要静态导入。

答案 1 :(得分:20)

概念

这是我使用ES6的解决方案

非常符合@ Bergi的回应,这是"模板"我在创建需要为class声明传递的参数的导入时使用。这用于我写的同构框架,因此可以在浏览器和node.js中使用转换器(我使用BabelWebpack):

<强> ./ 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();
}
// ...

我希望这有帮助!

答案 2 :(得分:7)

在@ Bergi answer的基础上使用debug module使用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!');

答案 3 :(得分:4)

我相信你可以使用es6模块加载器。 http://babeljs.io/docs/learn-es6/

System.import("lib/math").then(function(m) {
  m(youroptionshere);
});

答案 4 :(得分:2)

您只需要添加这两行。

import xModule from 'module';
const x = xModule('someOptions');

答案 5 :(得分:0)

我已经在这个线程上寻找相似的东西,并且想提出一个更好的恕我直言,至少在某些情况下,是解决方案(或者听听为什么不是这样)。

用例

我有一个模块,该模块在加载时立即运行一些实例化逻辑。我不喜欢在模块外部调用此初始化逻辑(与调用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

答案 6 :(得分:-1)

以下是我以调试模块为例的问题;

在该模块的npm页面上,您具有以下内容:

  

var debug = require('debug')('http')

在上面的行中,将字符串传递到导入的模块以进行构造。这是您在ES6中执行的操作


  

从'debug'导入{debug as Debug}   const debug = Debug('http');


希望这可以帮助某个人。