Javascript 如何有条件地导入 ES6 模块?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36367532/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:57:53  来源:igfitidea点击:

How can I conditionally import an ES6 module?

javascriptmoduleecmascript-6

提问by ericsoco

I need to do something like:

我需要做类似的事情:

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

The above code does not compile; it throws SyntaxError: ... 'import' and 'export' may only appear at the top level.

上面的代码不能编译;它抛出SyntaxError: ... 'import' and 'export' may only appear at the top level

I tried using System.importas shown here, but I don't know where Systemcomes from. Is it an ES6 proposal that didn't end up being accepted? The link to "programmatic API" from that article dumps me to a deprecated docs page.

我尝试使用System.import如图所示here,但我不知道System从哪里来。它是一个最终没有被接受的 ES6 提案吗?那篇文章中指向“编程 API”的链接将我转储到已弃用的文档页面

采纳答案by thecodeHyman

We do have dynamic imports proposal now with ECMA. This is in stage 3. This is also available as babel-preset.

我们现在有 ECMA 的动态导入提案。这是在第 3 阶段。这也可以作为babel-preset 使用

Following is way to do conditional rendering as per your case.

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

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

This basically returns a promise. Resolution of promise is expected to have the module. The proposal also have other features like multiple dynamic imports, default imports, js file import etc. You can find more information about dynamic imports here.

这基本上返回了一个承诺。承诺的决议有望有模块。该提案还具有其他功能,例如多个动态导入、默认导入、js 文件导入等。您可以在此处找到有关动态导入的更多信息。

回答by BaptWaels

If you'd like, you could use require. This is a way to have a conditional require statement.

如果您愿意,可以使用 require。这是一种使用条件 require 语句的方法。

let something = null;
let other = null;

if (condition) {
    something = require('something');
    other = require('something').other;
}
if (something && other) {
    something.doStuff();
    other.doOtherStuff();
}

回答by Kev

You can't import conditionally, but you can do the opposite: export something conditionally. It depends on your use case, so this work around might not be for you.

你不能有条件地导入,但你可以做相反的事情:有条件地导出一些东西。这取决于您的用例,因此这种解决方法可能不适合您。

You can do:

你可以做:

api.js

api.js

import mockAPI from './mockAPI'
import realAPI from './realAPI'

const exportedAPI = shouldUseMock ? mockAPI : realAPI
export default exportedAPI

apiConsumer.js

apiConsumer.js

import API from './api'
...

I use that to mock analytics libs like mixpanel, etc... because I can't have multiple builds or our frontend currently. Not the most elegant, but works. I just have a few 'if' here and there depending on the environment because in the case of mixpanel, it needs initialization.

我用它来模拟 mixpanel 等分析库……因为我目前不能有多个构建或我们的前端。不是最优雅的,但有效。根据环境,我在这里和那里只有一些“如果”,因为在 mixpanel 的情况下,它需要初始化。

回答by ericsoco

Looks like the answer is that, as of now, you can't.

看起来答案是,截至目前,你不能。

http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api

http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api

I think the intent is to enable static analysis as much as possible, and conditionally imported modules break that. Also worth mentioning -- I'm using Babel, and I'm guessing that Systemis not supported by Babel because the module loader API didn't become an ES6 standard.

我认为目的是尽可能地启用静态分析,而有条件导入的模块打破了这一点。还值得一提的是——我正在使用Babel,我猜SystemBabel 不支持它,因为模块加载器 API 没有成为 ES6 标准。

回答by Shoaib Nawaz

require()is a way to import some module on the run time and it equally qualifies for static analysis like importif used with string literal paths. This is required by bundler to pick dependencies for the bundle.

require()是一种在运行时导入某个模块的方法,它同样适用于静态分析,就像import与字符串文字路径一起使用一样。这是 bundler 为 bundle 选择依赖项所必需的。

const defaultOne = require('path/to/component').default;
const NamedOne = require('path/to/component').theName;

For dynamic module resolution with complete static analysis support, first index modules in an indexer(index.js) and import indexer in host module.

对于具有完整静态分析支持的动态模块解析,首先在索引器(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]);

回答by Solo

Important difference if you use dynamic import Webpack mode eager:

使用动态导入 Webpack 模式的重要区别eager

if (normalCondition) {
  // this will be included to bundle, whether you use it or not
  import(...);
}

if (process.env.SOMETHING === 'true') {
  // this will not be included to bundle, if SOMETHING is not 'true'
  import(...);
}

回答by Chris Marstall

obscuring it in an eval worked for me, hiding it from the static analyzer ...

在对我有用的 eval 中隐藏它,将它隐藏在静态分析器中......

if (typeof __CLI__ !== 'undefined') {
  eval("require('fs');")
}

回答by bradley2w1dl

I was able to achieve this using an immediately-invoked function and require statement.

我能够使用立即调用的函数和 require 语句来实现这一点。

const something = (() => (
  condition ? require('something') : null
))();

if(something) {
  something.doStuff();
}

回答by Elliot Ledger

Conditional imports could also be achieved with a ternary and require()s:

也可以使用三元和require()s来实现有条件的导入:

const logger = DEBUG ? require('dev-logger') : require('logger');

const logger = DEBUG ? require('dev-logger') : require('logger');

This example was taken from the ES Lint global-require docs: https://eslint.org/docs/rules/global-require

此示例取自 ES Lint global-require 文档:https: //eslint.org/docs/rules/global-require

回答by Ashok R

Look at this example for clear understanding of how dynamic import works.

查看此示例以清楚了解动态导入的工作原理。

Dynamic Module Imports Example

动态模块导入示例

To have Basic Understanding of importing and exporting Modules.

对导入和导出模块有基本的了解。

JavaScript modules Github

JavaScript 模块 Github

Javascript Modules MDN

Javascript 模块 MDN