我需要做类似的事情:
if (condition) {
import something from 'something';
}
// ...
if (something) {
something.doStuff();
}
以上代码无法编译;它抛出SyntaxError: ... 'import' and 'export' may only appear at the top level
。
我尝试使用显示here的System.import
,但我不知道System
来自哪里。是ES6提案还没有被接受吗?指向"程序化API"的链接从那篇文章中我转发到deprecated docs page。
答案 0 :(得分:86)
我们现在有ECMA的动态导入提案。这是在第3阶段。这也可以babel-preset。
以下是根据您的情况进行条件渲染的方法。
if (condition) {
import('something')
.then((something) => {
console.log(something.something);
});
}
这基本上是一个承诺。承诺的解决方案预计将有模块。该提案还具有其他功能,如多个动态导入,默认导入,js文件导入等。您可以找到有关dynamic imports here的更多信息。
答案 1 :(得分:83)
如果您愿意,可以使用require。这是一种获得条件需求声明的方法。
let something = null;
let other = null;
if (condition) {
something = require('something');
other = require('something').other;
}
if (something && other) {
something.doStuff();
other.doOtherStuff();
}
答案 2 :(得分:37)
你无法有条件地进口,但你可以做相反的事情:有条件地出口。这取决于您的使用案例,因此这可能不适合您。
你可以这样做:
api.js
import mockAPI from './mockAPI'
import realAPI from './realAPI'
const exportedAPI = shouldUseMock ? mockAPI : realAPI
export default exportedAPI
apiConsumer.js
import API from './api'
...
我用它来模拟像mixpanel这样的分析库...因为我目前不能有多个构建或我们的前端。不是最优雅,但有效。我只是有一些' if'这里和那里取决于环境,因为在mixpanel的情况下,它需要初始化。
答案 3 :(得分:9)
看起来答案是,截至目前,你不能。
http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api
我认为目的是尽可能地启用静态分析,并且有条件导入的模块会破坏它。另外值得一提的是 - 我使用Babel,并且我猜测Babel不支持System
,因为模块加载器API没有成为ES6标准。
答案 4 :(得分:2)
使用动态导入Webpack模式,
时的重要区别:
eager
答案 5 :(得分:1)
require()
是一种在运行时导入某些模块的方法,如果与字符串文字路径一起使用,它也同样适用于import
等静态分析。捆绑程序需要此选项来选择捆绑程序的依赖项。
const defaultOne = require('path/to/component').default;
const NamedOne = require('path/to/component').theName;
要获得具有完整静态分析支持的动态模块解析,请在索引器(index.js)中首先建立索引模块,然后在主机模块中导入索引器。
// index.js
export { default as ModuleOne } from 'path/to/module/one';
export { default as ModuleTwo } from 'path/to/module/two';
export { SomeNamedModule } from 'path/to/named/module';
// host.js
import * as indexer from 'index';
const moduleName = 'ModuleOne';
const Module = require(indexer[moduleName]);
答案 6 :(得分:0)
在为我工作的eval中隐藏它,将其隐藏在静态分析器中......
if (typeof __CLI__ !== 'undefined') {
eval("require('fs');")
}
答案 7 :(得分:0)
我能够使用立即调用的函数并需要require语句来实现这一点。
const something = (() => (
condition ? require('something') : null
))();
if(something) {
something.doStuff();
}
答案 8 :(得分:0)
答案 9 :(得分:0)
不,你不能!
但是,遇到这个问题应该使您重新思考如何组织代码。
在ES6模块之前,我们有CommonJS模块,它们使用require()语法。这些模块是“动态的”,这意味着我们可以根据代码中的条件导入新模块。 -来源:https://bitsofco.de/what-is-tree-shaking/
我猜想他们放弃对ES6的支持的原因之一是编译它非常困难或不可能的事实。
答案 10 :(得分:0)
const value = (
await import(`${condtion ? `./file1.js` : `./file2.js`}`)
).default
export default value