Nome da importação da variável ES6 em node.js?

é possível importar algo no módulo fornecendo o nome da variável ao usar a importação do ES6?

Ou seja, eu quero importar algum módulo em um tempo de execução, dependendo dos valores fornecidos em uma configuração:

import something from './utils/' + variableName; 

Não com a declaração de import . import e export são definidas de forma a serem estaticamente analisáveis, de modo que não podem depender de informações de tempo de execução.

Você está procurando a API do carregador (polyfill) , mas estou um pouco incerto sobre o status da especificação:

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

Além da resposta de Felix , observarei explicitamente que isso não é permitido atualmente pela gramática do ECMAScript 6 :

ImportDeclaration :

  • import ImportClause FromClause;

  • import ModuleSpecifier;

FromClause :

  • de ModuleSpecifier

ModuleSpecifier :

  • StringLiteral

Um ModuleSpecifier só pode ser um StringLiteral , não qualquer outro tipo de expressão como um AdditiveExpression .

Embora isso não seja realmente uma importação dinâmica (por exemplo, em minha circunstância, todos os arquivos que importo abaixo serão importados e empacotados pelo webpack, não selecionados em tempo de execução), um padrão que tenho usado e que pode ajudar em algumas circunstâncias :

 import Template1 from './Template1.js'; import Template2 from './Template2.js'; const templates = { Template1, Template2 }; export function getTemplate (name) { return templates[name]; } 

ou alternativamente:

 // 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; 

Eu não acho que posso voltar a um padrão tão facilmente com require() , que lança um erro se eu tentar importar um caminho de modelo construído que não existe.

Bons exemplos e comparações entre require e import podem ser encontrados aqui: http://www.2ality.com/2014/09/es6-modules-final.html

Excelente documentação sobre re-exportação de @iainastacio: http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles

Estou interessado em ouvir comentários sobre essa abordagem 🙂

Existe uma nova especificação que é chamada de importação dinâmica para módulos ES. Basicamente, você apenas chama import('./path/file.js') e é bom ir. A function retorna uma promise, que é resolvida com o módulo se a importação foi bem-sucedida.

 async function import() { try { const module = await import('./path/module.js'); } catch (error) { console.error('import failed'); } } 

Os principais casos de uso incluem a importação de módulos baseados em rotas para o Polymer 3.0, React e Vue, o que reduz a largura de banda de download porque os pacotes configuráveis ​​para as rotas são carregados apenas quando são necessários.

Aqui está a especificação proposta no Github .

No momento (janeiro de 2017), esse recurso está funcionando no Chrome 62. Os outros principais navegadores provavelmente estão captando esse recurso e implementando-o quando o suporte a ESmodule for totalmente suportado.

Editar:
Devo acrescentar que a especificação exige que as importações sejam estaticamente analisáveis, tanto a importação regular quanto a importação dinâmica, o que significa que você não pode usar um nome de variável para declarar seu caminho de importação. Portanto, não há solução para sua pergunta porque a especificação ES impede isso por design.

Eu menos gosto dessa syntax, mas funciona:
em vez de escrever

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

use esta syntax:

 let memberName = require("path" + "fileName"); 

você pode usar a notação não-ES6 para fazer isso. Isto é o que funcionou para mim:

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

Eu faria assim

 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