将选项传递给 ES6 module导入

IT技术 javascript module ecmascript-6 es6-modules
2021-02-01 20:44:22

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

你怎么翻译这个:

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

到 ES6?

6个回答

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

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

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

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

或者,如果您使用支持monadicPromise的module加载器,您可能可以执行以下操作

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

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

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

或者

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

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

@FelixKling 我完全同意你的看法。我正在转换一个旧的 express webapp,我遇到var session = require('express-session'); var RedisStore = require('connect-redis')(session);我只是想知道是否有一个单行解决方案。我完全可以通过将 RedisStore 分配分成两行来生存:)
2021-03-14 20:44:22
对于session/connect-redis示例,我一直在想象这样的语法:import session from 'express-session'); import RedisStore(session) from 'connect-redis'.
2021-03-19 20:44:22
谢谢我希望有类似import x from 'module' use someoptions;语法的东西
2021-03-23 20:44:22
@Fabrizio:如果你进一步考虑,它真的没有那么有用。它仅在module导出函数时才有效,并且如果我们已命名导入(即import {x, y} from 'module'),则可能不允许使用那么如果我想传递多个参数,语法应该是什么?或者传播一系列参数?这是一个狭窄的用例,基本上您正在尝试为函数调用添加不同的语法,但我们已经有了函数调用,可以处理所有其他情况。
2021-04-01 20:44:22
@FabrizioGiordano:我可以想象import {default(someoptions) as x} from 'module'在 ES7 中的东西,如果真的需要这样做的话。
2021-04-09 20:44:22

概念

这是我使用 ES6 的解决方案

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

我希望这有帮助!

@Swivel 请协助我在类似问题上需要帮助:stackoverflow.com/questions/55214957/...
2021-03-10 20:44:22
@jasonszhao 这里要注意的最重要的一点是,该类MyView扩展了框架命名空间中可用的某些项目。虽然完全可以将它作为参数简单地传递给类,但这也取决于类的实例化时间和位置;那么便携性就会受到影响。在实践中,这些类可能会被移交给其他可能以不同方式实例化它们的框架(例如,自定义 React 组件)。当类发现自己在框架范围之外时,由于这种方法,它在实例化时仍然可以保持对框架的访问。
2021-03-14 20:44:22
既然你导入的module都是类,那为什么在实例化类的时候不传参数呢?
2021-04-07 20:44:22

基于@Bergi 的使用 es6使用调试module答案如下

// 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!');
typescript with "module": "commonjs" and "esModuleInterop": true in tsconfig.js -import * as createPrompt from '../node_modules/prompt-sync'; const prompt = (createPrompt.default ?? createPrompt)();所以这适用于 tsc 和 ts-node 命令
2021-04-02 20:44:22

我相信你可以使用 es6 module加载器。 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 */})......但它不是很清楚。
2021-03-11 20:44:22
哇,我不敢相信在 E6 中没有优雅的方法可以做到这一点。这就是我主要编写module的方式。
2021-03-16 20:44:22

您只需要添加这两行。

import xModule from 'module';
const x = xModule('someOptions');
这只是将参数传递给您已导入并正在调用的函数。它没有将任何选项传递给您从中导入它的modulexModule在这里误导。你实际上拥有的是import func from 'module'; func('someOptions');.
2021-03-20 20:44:22