eS6インポートの使用中に変数名を提供するモジュールに何かをインポートすることは可能ですか?
つまり構成で提供される値に応じて、実行時にいくつかのモジュールをインポートしたい:
import something from './utils/' + variableName;
import
ステートメントではありません。 import
およびexport
は、静的に分析できるように定義されているため、ランタイム情報に依存できません。
loader API(polyfill) を探していますが、仕様のステータスについては少しわかりません:
System.import('./utils/' + variableName).then(function(m) {
console.log(m);
});
Felixの答え に加えて、これが ECMAScript 6文法 によって現在許可されていないことに明示的に注意します。
ImportDeclaration:
importImportClause FromClause;
importModuleSpecifier;
FromClause:
- fromModuleSpecifier
ModuleSpecifier:
- StringLiteral
ModuleSpecifierはStringLiteralのみで、AdditiveExpression。
これは実際には動的なインポートではありませんが(たとえば、私の状況では、以下でインポートするすべてのファイルは、実行時に選択されずにwebpackによってインポートおよびバンドルされます)、いくつかの状況で役立つ可能性のある使用しているパターンは:
import Template1 from './Template1.js';
import Template2 from './Template2.js';
const templates = {
Template1,
Template2
};
export function getTemplate (name) {
return templates[name];
}
または、代わりに:
// index.js
export { default as Template1 } from './Template1';
export { default as Template2 } from './Template2';
// OtherComponent.js
import * as templates from './index.js'
...
// handy to be able to fall back to a default!
return templates[name] || templates.Template1;
require()
を使用してデフォルトに簡単にフォールバックできるとは思わないが、存在しない構築済みのテンプレートパスをインポートしようとするとエラーがスローされる。
Requireとimportの良い例と比較はここにあります: http://www.2ality.com/2014/09/es6-modules-final.html
@iainastacioからの再エクスポートに関する優れたドキュメント: http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles
私はこのアプローチに関するフィードバックを聞くことに興味があります:)
ESモジュールのdynamic importと呼ばれる新しい仕様があります。基本的に、あなたはimport('./path/file.js')
を呼び出すだけでいいのです。この関数はプロミスを返します。これは、インポートが成功した場合にモジュールで解決されます。
async function import() {
try {
const module = await import('./path/module.js');
} catch (error) {
console.error('import failed');
}
}
ユースケースには、React、Vueなどのルートベースのコンポーネントインポート、および遅延ロードモジュール、実行時に必要な場合。
Google Developers の説明を次に示します。
MDN によると、現在のすべてのChromeブラウザと、Firefox 66のフラグの後ろでサポートされています。
そのためには、非ES6表記を使用できます。これは私のために働いたものです:
let myModule = null;
if (needsToLoadModule) {
myModule = require('my-module').default;
}
この構文はあまり好きではありませんが、機能します。
書く代わりに
import memberName from "path" + "fileName";
// this will not work!, since "path" + "fileName" need to be string literal
次の構文を使用します。
let memberName = require("path" + "fileName");
Node.jsでES6 import
について具体的に尋ねられた質問を理解していますが、以下は、より一般的なソリューションを探している人に役立つかもしれません。
let variableName = "es5.js";
const something = require(`./utils/${variableName}`);
ES6モジュールをインポートする場合であり、default
エクスポートにアクセスする必要がある場合は、次のいずれかを使用する必要があります。
let variableName = "es6.js";
// Assigning
const defaultMethod = require(`./utils/${variableName}`).default;
// Accessing
const something = require(`./utils/${variableName}`);
something.default();
また、このアプローチでデストラクタリングを使用することもできます。これにより、他のインポートの構文に慣れ親しむことができます。
// Destructuring
const { someMethod } = require(`./utils/${variableName}`);
someMethod();
残念ながら、default
にアクセスするだけでなく、構造化する場合は、複数の手順でこれを実行する必要があります。
// ES6 Syntax
Import defaultMethod, { someMethod } from "const-path.js";
// Destructuring + default assignment
const something = require(`./utils/${variableName}`);
const defaultMethod = something.default;
const { someMethod, someOtherMethod } = something;
私はこのようにします
function load(filePath) {
return () => System.import(`${filePath}.js`);
// Note: Change .js to your file extension
}
let A = load('./utils/' + variableName)
// Now you can use A in your module
Dynamic import() (Chrome 63+で利用可能)はあなたの仕事をします。方法は次のとおりです。
let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });