使用ES6导入时是否可以将某些内容导入提供变量名称的模块中?
即我想根据配置中提供的值在运行时导入一些模块:
import something from './utils/' + variableName;
使用ES6导入时是否可以将某些内容导入提供变量名称的模块中?
即我想根据配置中提供的值在运行时导入一些模块:
import something from './utils/' + variableName;
Answers:
不与import
声明。import
并export
以可静态分析的方式进行定义,因此它们不能依赖于运行时信息。
您正在寻找loader API(polyfill),但是我对规范的状态尚不清楚:
System.import('./utils/' + variableName).then(function(m) {
console.log(m);
});
除了Felix的回答,我将明确指出,ECMAScript 6语法当前不允许这样做:
ImportDeclaration :
import ImportClause FromClause;
导入 ModuleSpecifier;
FromClause :
- 来自 ModuleSpecifier
ModuleSpecifier :
- 字符串字面量
甲ModuleSpecifier只能是一个串文字,而不是任何其他种类等的表达的AdditiveExpression。
const
string literal
s。它们是静态可分析的,不是吗?这将使重用依赖项的位置成为可能。(例如,导入模板,并同时提供模板和模板的位置)。
虽然这实际上不是动态导入(例如,在我的情况下,我要在下面导入的所有文件都将由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
我很想听听对此方法的反馈意见:)
Object.values(templates)
。
有一个新规范,称为ES模块动态导入。基本上,您只需打电话import('./path/file.js')
就可以了。该函数返回一个promise,如果导入成功,则与模块一起解析。
async function importModule() {
try {
const module = await import('./path/module.js');
} catch (error) {
console.error('import failed');
}
}
用例包括针对React,Vue等的基于路由的组件导入,以及在运行时需要时,可以懒加载模块的能力。
这是有关Google Developers的说明。
据MDN称,当前所有主流浏览器(IE除外)均支持该功能,并且caniuse.com在全球市场份额中显示87%的支持。同样,不支持IE或非铬Edge。
我了解import
Node.js中特别针对ES6提出的问题,但以下内容可能会帮助其他人寻求更通用的解决方案:
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;
我不太喜欢这种语法,但是它可以工作:
而不是编写
import memberName from "path" + "fileName";
// this will not work!, since "path" + "fileName" need to be string literal
使用以下语法:
let memberName = require("path" + "fileName");
require()
是用于加载文件的Node.JS方法,这是早期版本。import
statement是较新的版本,现在已成为官方语言语法的一部分。但是,在许多情况下,浏览器将使用以前的版本(在科学之后)。require语句还将兑现您的文件,因此,如果第二次加载文件,则会从内存中加载文件(性能更好)。导入方式有其自身的好处-如果您使用的是WebPack。然后webpack可以删除无效引用(这些脚本不会下载到客户端)。
动态import()(在Chrome 63+中可用)可以完成您的工作。这是如何做:
let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
./utils/test.js
export default () => {
doSomething...
}
从文件呼叫
const variableName = 'test';
const package = require(`./utils/${variableName}`);
package.default();