Javascript 将选项传递给 ES6 模块导入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29923879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:19:48  来源:igfitidea点击:

Pass options to ES6 module imports

javascriptmoduleecmascript-6es6-modules

提问by Fabrizio Giordano

Is it possible to pass options to ES6 imports?

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

How do you translate this:

你怎么翻译这个:

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

to ES6?

到 ES6?

回答by Bergi

There is no way to do this with a single importstatement, it does not allow for invocations.

使用单个import语句无法做到这一点,它不允许调用。

So you wouldn't call it directly, but you can basically do just the same what commonjs does with default exports:

所以你不会直接调用它,但你基本上可以像 commonjs 对默认导出所做的那样做:

// module.js
export default function(options) {
    return {
        // actual module
    }
}

// main.js
import m from 'module';
var x = m(someoptions);

Alternatively, if you use a module loader that supports monadicpromises, you might be able to do something like

或者,如果您使用支持monadic承诺的模块加载器,您可能可以执行以下操作

System.import('module').ap(someoptions).then(function(x) {
    …
});

With the new importoperatorit might become

有了新的import运营商,它可能会变成

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

or

或者

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

however you probably don't want a dynamic import but a static one.

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

回答by Swivel

Concept

概念

Here's my solution using ES6

这是我使用 ES6 的解决方案

Very much inline with @Bergi's response, this is the "template" I use when creating imports that need parameters passed for classdeclarations. This is used on an isomorphic framework I'm writing, so will work with a transpiler in the browser and in node.js (I use Babelwith Webpack):

非常符合@Bergi 的响应,这是我在创建需要为class声明传递参数的导入时使用的“模板” 。这用于我正在编写的同构框架,因此将与浏览器和 node.js 中的转译器一起使用(我使用Babelwith Webpack):

./MyClass.js

./MyClass.js

export default (Param1, Param2) => class MyClass {
    constructor(){
        console.log( Param1 );
    }
}

./main.js

./main.js

import MyClassFactory from './MyClass.js';

let MyClass = MyClassFactory('foo', 'bar');

let myInstance = new MyClass();

The above will output fooin a console

以上将foo在控制台中输出

EDIT

编辑

Real World Example

真实世界示例

For a real world example, I'm using this to pass in a namespace for accessing other classes and instances within a framework. Because we're simply creating a function and passing the object in as an argument, we can use it with our class declaration likeso:

对于现实世界的示例,我使用它来传递名称空间以访问框架内的其他类和实例。因为我们只是创建一个函数并将对象作为参数传入,所以我们可以像这样在类声明中使用它:

export default (UIFramework) => class MyView extends UIFramework.Type.View {
    getModels() {
        // ...
        UIFramework.Models.getModelsForView( this._models );
        // ...
    }
}

The importation is a bit more complicated and automagicalin my case given that it's an entire framework, but essentially this is what is happening:

导入有点复杂,automagical在我的情况下,考虑到它是一个完整的框架,但基本上这是正在发生的事情:

// ...
getView( viewName ){
    //...
    const ViewFactory = require(viewFileLoc);
    const View = ViewFactory(this);
    return new View();
}
// ...

I hope this helps!

我希望这有帮助!

回答by mummybot

Building on @Bergi's answerto use the debug moduleusing es6 would be the following

基于@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!');

回答by user895715

I believe you can use es6 module loaders. http://babeljs.io/docs/learn-es6/

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

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

回答by Mansi Teharia

You just need to add these 2 lines.

您只需要添加这两行。

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

回答by Akinwale Folorunsho Habib

Here's my take on this question using the debug module as an example;

这是我以调试模块为例对这个问题的看法;

On this module's npm page, you have this:

在这个模块的 npm 页面上,你有这个:

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

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

In the line above, a string is passed to the module that is imported, to construct. Here's how you would do same in ES6

在上面的行中,将一个字符串传递给导入的模块以进行构造。下面是你在 ES6 中的做法



import { debug as Debug } from 'debug' const debug = Debug('http');

import { debug as Debug } from 'debug' const debug = Debug('http');



Hope this helps someone out there.

希望这可以帮助那里的人。

回答by GullerYA

I've landed on this thread looking up for somewhat similar and would like to propose a better, IMHO, at least in some cases, solution (or hear why it is not so).

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

Use case

用例

I have a module, that is running some instantiation logic immediately upon loading. I do notlike to call this init logic outside the module (which is the same as call new SomeClass(p1, p2)or new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })and alike).

我有一个模块,它在加载时立即运行一些实例化逻辑。我喜欢在模块外部调用这个 init 逻辑(这与 callnew SomeClass(p1, p2)new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })类似)。

I do like that this init logic will run once, kind of a singular instantiation flow, butonce per some specific parametrized context.

我确实喜欢这个 init 逻辑将运行一次,有点像一个单一的实例化流程,每个特定的参数化上下文一次。

Example

例子

service.jshas at its very basic scope:

service.js在其非常基本的范围内:

let context = null;                  // meanwhile i'm just leaving this as is
console.log('initialized in context ' + (context ? context : 'root'));

Module A does:

模块 A 执行以下操作:

import * as S from 'service.js';     // console has now "initialized in context root"

Module B does:

模块 B 执行以下操作:

import * as S from 'service.js';     // console stays unchanged! module's script runs only once

So far so good: service is available for both modules but was initialized only once.

到目前为止一切顺利:服务可用于两个模块,但仅初始化一次。

Problem

问题

How to make it run as another instance and init itself once again in another context, say in Module C?

如何让它作为另一个实例运行并在另一个上下文中再次初始化自己,比如在模块 C 中?

Solution?

解决方案?

This is what I'm thinking about: use query parameters. In the service we'd add the following:

这就是我在想的:使用查询参数。在服务中,我们将添加以下内容:

let context = new URL(import.meta.url).searchParams.get('context');

let context = new URL(import.meta.url).searchParams.get('context');

Module C would do:

模块 C 会做:

import * as S from 'service.js?context=special';

the module will be re-imported, it's basic init logic will run and we'll see in the console:

模块将被重新导入,它的基本初始化逻辑将运行,我们将在控制台中看到:

initialized in context special

initialized in context special