Javascript node.js 中的 ES6 变量导入名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29168433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ES6 variable import name in node.js?
提问by Vytautas Butkus
is it possible to import something into module providing variable name while using ES6 import?
是否可以在使用 ES6 导入时将某些内容导入提供变量名称的模块?
I.e. I want to import some module at a runtime depending on values provided in a config:
即我想在运行时根据配置中提供的值导入一些模块:
import something from './utils/' + variableName;
采纳答案by Felix Kling
Not with the importstatement. importand exportare defined in such a way that they are statically analyzable, so they cannot depend on runtime information.
与import声明无关。import并且export以它们可静态分析的方式定义,因此它们不能依赖于运行时信息。
You are looking for the loader API (polyfill), but I'm a bit unclear about the status of the specification:
您正在寻找loader API (polyfill),但我对规范的状态有点不清楚:
System.import('./utils/' + variableName).then(function(m) {
console.log(m);
});
回答by apsillers
In addition to Felix's answer, I'll note explicitly that this is not currently allowed by the ECMAScript 6 grammar:
除了Felix 的回答之外,我还要明确指出ECMAScript 6 语法目前不允许这样做:
ImportDeclaration:
importImportClause FromClause ;
importModuleSpecifier ;
FromClause:
- fromModuleSpecifier
ModuleSpecifier:
- StringLiteral
进口声明:
导入ImportClause FromClause ;
导入模块说明符;
FromClause :
- 来自模块说明符
模块说明符:
- 字符串字面量
A ModuleSpecifiercan only be a StringLiteral, not any other kind of expression like an AdditiveExpression.
甲ModuleSpecifier只能是一个串文字,而不是任何其他种类等的表达的AdditiveExpression。
回答by ptim
Whilst this is not actually a dynamic import (eg in my circumstance, all the files I'm importing below will be imported and bundled by webpack, not selected at runtime), a pattern I've been using which may assist in some circumstances is:
虽然这实际上不是动态导入(例如,在我的情况下,我在下面导入的所有文件都将由 webpack 导入和捆绑,而不是在运行时选择),但我一直在使用的一种模式可能在某些情况下有所帮助:
import Template1 from './Template1.js';
import Template2 from './Template2.js';
const templates = {
Template1,
Template2
};
export function getTemplate (name) {
return templates[name];
}
or alternatively:
或者:
// 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;
I don't think I can fall back to a default as easily with require(), which throws an error if I try to import a constructed template path that doesn't exist.
我不认为我可以使用 轻松回退到默认值require(),如果我尝试导入不存在的构造模板路径,则会引发错误。
Good examples and comparisons between require and import can be found here: http://www.2ality.com/2014/09/es6-modules-final.html
可以在此处找到 require 和 import 之间的良好示例和比较:http: //www.2ality.com/2014/09/es6-modules-final.html
Excellent documentation on re-exporting from @iainastacio: http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles
关于从@iainastacio 重新导出的优秀文档:http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles
I'm interested to hear feedback on this approach :)
我很想听听关于这种方法的反馈:)
回答by Nicolai Schmid
There is a new specification which is called a dynamic importfor ES modules.
Basically, you just call import('./path/file.js')and you're good to go. The function returns a promise, which resolves with the module if the import was successful.
有一个新规范,称为ES 模块的动态导入。基本上,你只要打电话import('./path/file.js')就可以了。该函数返回一个承诺,如果导入成功,该承诺将与模块一起解析。
async function import() {
try {
const module = await import('./path/module.js');
} catch (error) {
console.error('import failed');
}
}
Use cases
用例
Use-cases include route based component importing for React, Vueetc and the ability to lazy load modules, once they are required during runtime.
用例包括React、Vue等基于路由的组件导入以及延迟加载模块的能力,一旦它们在运行时需要。
Further Information
更多信息
Here's is an explanation on Google Developers.
这是对Google Developers的解释。
Browser compatibility (April 2020)
浏览器兼容性(2020 年 4 月)
According to MDNit is supported by every current major browser (except IE) and caniuse.comshows 87% support across the global market share. Again no support in IE or non-chromium Edge.
据MDN 称,目前所有主流浏览器(IE 除外)都支持它,caniuse.com在全球市场份额中显示 87% 的支持。再次不支持 IE 或非铬 Edge。
回答by MCTaylor17
I understand the question specifically asked for ES6 importin Node.js, but the following might help others looking for a more generic solution:
我了解importNode.js 中专门针对 ES6 提出的问题,但以下内容可能会帮助其他人寻找更通用的解决方案:
let variableName = "es5.js";
const something = require(`./utils/${variableName}`);
Note if you're importing an ES6 moduleand need to access the defaultexport, you will need to use one of the following:
请注意,如果您要导入 ES6 模块并需要访问default导出,则需要使用以下选项之一:
let variableName = "es6.js";
// Assigning
const defaultMethod = require(`./utils/${variableName}`).default;
// Accessing
const something = require(`./utils/${variableName}`);
something.default();
You can also use destructuring with this approach which may add more syntax familiarity with your other imports:
您还可以通过这种方法使用解构,这可能会增加您对其他导入的语法熟悉度:
// Destructuring
const { someMethod } = require(`./utils/${variableName}`);
someMethod();
Unfortunately, if you want to access defaultas well as destructuring, you will need to perform this in multiple steps:
不幸的是,如果您既要访问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;
回答by mlevanon
you can use the non-ES6 notation to do that. this is what worked for me:
你可以使用非 ES6 符号来做到这一点。这对我有用:
let myModule = null;
if (needsToLoadModule) {
myModule = require('my-module').default;
}
回答by Gil Epshtain
I less like this syntax, but it work:
instead of writing
我不太喜欢这种语法,但它有效:
而不是写作
import memberName from "path" + "fileName";
// this will not work!, since "path" + "fileName" need to be string literal
use this syntax:
使用这个语法:
let memberName = require("path" + "fileName");
回答by Velojet
Dynamic import()(available in Chrome 63+) will do your job. Here's how:
动态导入()(在 Chrome 63+ 中可用)将完成您的工作。就是这样:
let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
回答by Andres Munoz
./utils/test.js
./utils/test.js
export default () => {
doSomething...
}
call from file
从文件调用
const variableName = 'test';
const package = require(`./utils/${variableName}`);
package.default();
回答by april
I would do it like this
我会这样做
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

