我需要做一些类似的事情:

if (condition) {
    import something from 'something';
}
// ...
if (something) {
    something.doStuff();
}

上面的代码不能编译;它抛出SyntaxError:…“import”和“export”只能出现在顶层。

我尝试使用系统。导入如下所示,但我不知道系统来自哪里。是ES6提案最终没有被接受吗?那篇文章中的“程序化API”链接把我扔到了一个废弃的文档页面。


当前回答

你不能有条件地进口,但你可以做相反的事情:有条件地出口。这取决于您的用例,所以这种方法可能不适合您。

你可以:

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的情况下,它需要初始化。

其他回答

我们现在有ECMA的动态进口建议。这是第三阶段。这也可作为babel预设。

以下是根据您的情况进行条件渲染的方法。

if (condition) {
    import('something')
    .then((something) => {
       console.log(something.something);
    });
}

这基本上返回了一个承诺。决议的承诺是有预期的模块。该建议还具有其他功能,如多个动态导入,默认导入,js文件导入等。您可以在这里找到关于动态导入的更多信息。

不,你不能!

然而,遇到这个问题应该让你重新思考如何组织代码。

在ES6模块之前,我们有使用require()语法的CommonJS模块。这些模块是“动态的”,这意味着我们可以根据代码中的条件导入新模块。-来源:https://bitsofco.de/what-is-tree-shaking/

我猜他们在ES6上放弃支持的原因之一是编译它非常困难或不可能。

在JS中有条件地导入和导出

const value = (
    await import(`${condtion ? `./file1.js` : `./file2.js`}`)
).default

export default value

Require()是一种在运行时导入某些模块的方法,如果与字符串文本路径一起使用,它同样有资格进行静态分析。这是捆绑器为捆绑包选择依赖项所必需的。

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]);

你可以通过下面的链接了解更多关于动态导入的知识

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports