是否可以使用下面的条件导入语句?
if (foo === bar) {
import Baz from './Baz';
}
我已尝试过上述内容,但在编译时会收到以下错误(来自Babel)。
'import' and 'export' may only appear at the top level
是否可以使用如下的动态导入语句?
for (let foo in bar) {
if (bar.hasOwnProperty(foo)) {
import Baz from `./${foo}`;
}
}
以上在编译时从Babel收到同样的错误。
这是可能做的还是我缺少的东西?
我试图这样做的原因是我有很多“页面”的导入,它们遵循类似的模式。我想通过动态for循环导入这些文件来清理我的代码库。
如果无法做到这一点,那么有更好的方法来处理ES6中的大量导入吗?
答案 0 :(得分:32)
我们现在有ECMA的动态导入提案。这是在第2阶段。这也可以babel-preset。
以下是根据您的情况进行条件渲染的方法。
if (foo === bar) {
import('./Baz')
.then((Baz) => {
console.log(Baz.Baz);
});
}
这基本上是一个承诺。承诺的解决方案预计将有模块。该提案还包含多个动态导入,默认导入,js文件导入等。您可以找到有关dynamic imports here的更多信息。
答案 1 :(得分:21)
您无法动态解决依赖关系,因为imports
适用于静态分析。但是,你可以在这里使用一些require
,例如:
for (let foo in bar) {
if (bar.hasOwnProperty(foo)) {
const Baz = require(foo).Baz;
}
}
答案 2 :(得分:7)
由于这个问题在Google的高度评价中,因此值得一提的是,自从发布了较早的答案以来,情况已经发生了变化。
MDN在Dynamic Imports下有此条目:
可以将import关键字称为动态导入 模块。当以这种方式使用时,它将返回一个promise。
import('/modules/my-module.js') .then((module) => { // Do something with the module. }); // This form also supports the await keyword. let module = await import('/modules/my-module.js');
有关该主题的有用文章可以在Medium上找到。
答案 3 :(得分:2)
要求无法解决您的问题,因为它是同步通话。有几个选项,它们都涉及
在ECMA Script中,支持使用SystemJS的延迟加载模块。当然,并非所有浏览器都支持此功能,因此在此期间您可以使用JSPM或SystemJS垫片。
答案 4 :(得分:1)
自2016年以来,JavaScript世界已经过去了很多,所以我认为是时候提供有关此主题的最新信息。当前 Dynamic imports都是现实的 on Node和on browsers(如果您不关心IE,则自然可以;如果您确实关心IE,则可以@babel/plugin-syntax-dynamic-import) )。
因此,请考虑一个示例模块something.js
,该模块具有两个命名的导出和一个默认的导出:
export const hi = (name) => console.log(`Hi, ${name}!`)
export const bye = (name) => console.log(`Bye, ${name}!`)
export default () => console.log('Hello World!')
我们可以使用import()
语法轻松,干净地有条件地加载它:
if (somethingIsTrue) {
import('./something.js').then((module) => {
// Use the module the way you want, as:
module.hi('Erick') // Named export
module.bye('Erick') // Named export
module.default() // Default export
})
}
但是由于返回值是Promise
,因此async
/ await
语法糖也是可能的:
async imAsyncFunction () {
if (somethingIsTrue) {
const module = await import('./something.js')
module.hi('Erick')
}
}
现在考虑一下Object Destructuring Assignment带来的可能性!例如,我们能够轻松地将只有一个名为exports的内容存储在内存中以供以后使用:
const { bye } = await import('./something.js')
bye('Erick')
或者获取其中一个名为export的文件并将其重命名为我们想要的其他名称:
const { hi: hello } = await import('./something.js')
hello('Erick')
或者甚至将默认导出的函数重命名为更有意义的东西:
const { default: helloWorld } = await import('./something.js')
helloWorld()
仅是最后(但并非最不重要)的说明: import()
看起来像函数调用,但不是Function
。这是一种特殊的语法,恰好使用括号(类似于super()
的情况)。因此,不可能将import
分配给变量或使用Function
原型的东西,例如call
/ apply
。