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

IT技术 javascript node.js ecmascript-6
2021-01-12 06:19:57

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

即我想在运行时根据配置中提供的值导入一些module:

import something from './utils/' + variableName;
6个回答

import声明无关。import并且export以它们可静态分析的方式定义,因此它们不能依赖于运行时信息。

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

System.import('./utils/' + variableName).then(function(m) {
  console.log(m);
});
我需要“要求”系统吗?它不在全球范围内.. Ps 我正在使用 babel js
2021-03-12 06:19:57
刚刚检查过,它有点工作(尝试加载文件)但随后弄乱了其他module的路径......太糟糕了它本身不支持......
2021-03-12 06:19:57
这仍然是一个问题吗?我需要动态加载 ES6 module,但我没有成功..
2021-03-17 06:19:57
它尚未在任何地方实施 AFAIK。您必须使用链接中的 polyfill。
2021-04-03 06:19:57

虽然这实际上不是动态导入(例如,在我的情况下,我在下面导入的所有文件都将由 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

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

点赞。我使用了“或替代”的方法。对我的自定义本地化解决方案来说就像一个魅力。
2021-03-17 06:19:57
我应该想到这一点。很好的解决方案,无论您如何导入东西(即使您没有导入任何东西)。是否有您想稍后获取名称或按名称获取的项目列表?将它们放在对象字面量而不是数组字面量中,并让对象语法根据它们的局部常量/变量名称来命名它们。如果您再次需要它们作为列表,只需执行Object.values(templates).
2021-03-24 06:19:57
谢谢,这是简单地解决这个问题的好方法。非常感激。
2021-03-25 06:19:57

除了Felix 的回答之外,我还要明确指出ECMAScript 6 语法目前不允许这样做

进口声明

  • 导入 ImportClause FromClause ;

  • 导入module说明 符;

FromClause :

  • 来自module说明

module说明符

  • 字符串字面量

ModuleSpecifier只能是一个串文字,而不是任何其他种类等的表达的AdditiveExpression

很遗憾这没有扩展到包括const string literals。它们是静态可分析的,不是吗?这将使重用依赖项的位置成为可能。(例如,导入模板并同时提供模板和模板位置)。
2021-03-26 06:19:57

有一个新规范,称为ES module动态导入基本上,你只要打电话import('./path/file.js')就可以了。该函数返回一个Promise,如果导入成功,该Promise将与module一起解析。

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

用例

用例包括React、Vue等的基于路由的组件导入以及延迟加载module的能力,一旦它们在运行时需要。

更多信息

这是对Google Developers的解释

浏览器兼容性(2020 年 4 月)

MDN 称,目前所有主流浏览器(IE 除外)都支持它,caniuse.com在全球市场份额中显示 87% 的支持。再次不支持 IE 或非铬边缘。

你确定你的编辑?该提案显示了一个带有可变路径的示例:github.com/tc39/proposal-dynamic-import#example
2021-03-25 06:19:57
@Blauhirn 我是,但你的链接清楚地表明这是一种可能性。虽然我不知道 webpack 是如何解决这些导入的
2021-03-25 06:19:57
是的,您可以按原样在浏览器中运行它们。但是 webpack 会自动使用导入将您的应用程序拆分为多个包,用于应用程序的不同部分,例如路由。我一直在使用它们,它们真的很有帮助。就“处理”而言;webpack 将通过 babel 导入,这将为旧浏览器填充该功能。
2021-03-26 06:19:57
需要明确的是:动态 import()与变量一起使用,并且不需要是静态可分析的(这就是“动态”的全部意义,当然?)。看我的回答。
2021-03-26 06:19:57
如果我错了,请纠正我,但 webpack 不处理这些,是吗?我认为这是它们在浏览器中“按原样”运行的动态导入点。
2021-03-27 06:19:57

我了解importNode.js 中专门针对 ES6 提出的问题,但以下内容可能会帮助其他人寻找更通用的解决方案:

let variableName = "es5.js";
const something = require(`./utils/${variableName}`);

请注意,如果您要导入 ES6 module并需要访问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;