web-dev-qa-db-ja.com

node.jsのES6変数インポート名?

eS6インポートの使用中に変数名を提供するモジュールに何かをインポートすることは可能ですか?

つまり構成で提供される値に応じて、実行時にいくつかのモジュールをインポートしたい:

import something from './utils/' + variableName;
96
Vytautas Butkus

importステートメントではありません。 importおよびexportは、静的に分析できるように定義されているため、ランタイム情報に依存できません。

loader API(polyfill) を探していますが、仕様のステータスについては少しわかりません:

System.import('./utils/' + variableName).then(function(m) {
  console.log(m);
});
60
Felix Kling

Felixの答え に加えて、これが ECMAScript 6文法 によって現在許可されていないことに明示的に注意します。

ImportDeclaration

  • importImportClause FromClause;

  • importModuleSpecifier;

FromClause

  • fromModuleSpecifier

ModuleSpecifier

  • StringLiteral

ModuleSpecifierStringLiteralのみで、AdditiveExpression

25
apsillers

これは実際には動的なインポートではありませんが(たとえば、私の状況では、以下でインポートするすべてのファイルは、実行時に選択されずに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

私はこのアプローチに関するフィードバックを聞くことに興味があります:)

24
ptim

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のフラグの後ろでサポートされています。

10
Nicolai Schmid

そのためには、非ES6表記を使用できます。これは私のために働いたものです:

let myModule = null;
if (needsToLoadModule) {
  myModule = require('my-module').default;
}
3
mlevanon

この構文はあまり好きではありませんが、機能します。
書く代わりに

import memberName from "path" + "fileName"; 
// this will not work!, since "path" + "fileName" need to be string literal

次の構文を使用します。

let memberName = require("path" + "fileName");
3
Gil Epshtain

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;
1
MCTaylor17

私はこのようにします

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
0
april

Dynamic import() (Chrome 63+で利用可能)はあなたの仕事をします。方法は次のとおりです。

let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
0
Velojet