node.js中的ES6变量导入名称?

时间:2015-03-20 14:06:22

标签: javascript node.js ecmascript-6

是否可以在使用ES6导入时将某些内容导入到提供变量名称的模块中?

即。我想在运行时导入一些模块,具体取决于配置中提供的值:

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

11 个答案:

答案 0 :(得分:57)

不使用import语句。 importexport的定义方式是静态可分析的,因此它们不能依赖于运行时信息。

您正在寻找loader API (polyfill),但我对规范的状态有点不清楚:

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

答案 1 :(得分:25)

除了Felix's answer之外,我还会明确指出ECMAScript 6 grammar目前不允许这样做:

  

ImportDeclaration

     
      
  • 导入 ImportClause FromClause;

  •   
  • 导入 ModuleSpecifier;

  •   
     

FromClause

     
      
  • 来自 ModuleSpecifier
  •   
     

ModuleSpecifier

     
      
  • 串文字
  •   

ModuleSpecifier 只能是 StringLiteral ,而不是 AdditiveExpression 等任何其他类型的表达式。

答案 2 :(得分:24)

虽然这实际上不是动态导入(例如,在我的情况下,我在下面导入的所有文件都将由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()回退到默认值,如果我尝试导入不存在的构造模板路径,则会抛出错误。

需要和导入之间的良好示例和比较可以在这里找到:http://www.2ality.com/2014/09/es6-modules-final.html

有关从@iainastacio重新导出的优秀文档: http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles

我很想听听有关这种方法的反馈:)

答案 3 :(得分:7)

ES模块有一个新规范称为动态导入。 基本上,你只需拨打import('./path/file.js')即可。该函数返回一个promise,如果导入成功,它将与模块​​一起解析。

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中支持它。

答案 4 :(得分:3)

您可以使用非ES6表示法来执行此操作。这对我有用:

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

答案 5 :(得分:3)

我不太喜欢这种语法,但它起作用:
而不是写作

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

使用以下语法:

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

答案 6 :(得分:1)

我了解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;

答案 7 :(得分:0)

我会这样做

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

答案 8 :(得分:0)

Dynamic import()(适用于Chrome 63+)将完成您的工作。方法如下:

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

答案 9 :(得分:0)

./ utils / test.js

export default () => {
  doSomething...
}

从文件中调用

const variableName = 'test';
const package = require(`./utils/${variableName}`);
package.default();

答案 10 :(得分:0)

我在使用 Vue.js 时遇到了类似的问题:当您在构建时在 import(variableName) 中使用变量时,Webpack 不知道去哪里寻找。因此,您必须将其限制为具有适当扩展名的已知路径:

let something = import("@/" + variableName + ".js") 

That 在 github 中针对同一问题的回答对我非常有帮助。