web-dev-qa-db-ja.com

ES6モジュールのインポートにオプションを渡す

ES6インポートにオプションを渡すことは可能ですか?

これをどのように翻訳しますか:

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

eS6へ?

129

単一のimportステートメントでこれを行う方法はありません。呼び出しは許可されません。

したがって、直接呼び出すことはできませんが、基本的にcommonjsがデフォルトのエクスポートで行うことと同じことを行うことができます。

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

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

あるいは、 monadic promiseをサポートするモジュールローダーを使用すると、次のようなことができるかもしれません

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

新しい import演算子 では、

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

または

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

ただし、おそらく動的インポートではなく、静的インポートが必要です。

93
Bergi

概念

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

これがお役に立てば幸いです!

20
Swivel

@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!');
9
mummybot

Es6モジュールローダーを使用できると思います。 http://babeljs.io/docs/learn-es6/

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

これらの2行を追加するだけです。

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

私はこのスレッドにやや似たものを探して着陸しましたが、少なくともいくつかのケースでは、より良いIMHOの解決策を提案したいと思います(またはそうでない理由を聞いてください)。

ユースケース

モジュールがあり、ロードするとすぐにインスタンス化ロジックが実行されます。 notモジュールの外でこの初期化ロジックを呼び出したい(これはnew SomeClass(p1, p2)new ((p1, p2) => class SomeClass { ... p1 ... p2 ... })などを呼び出すのと同じです)。

この初期化ロジックは、特定のインスタンス化フローの一種であるbut特定のパラメーター化されたコンテキストごとに1回実行されるようにします。

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

0
GullerYA