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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何有条件地导入ES6模块?相关的知识,希望对你有一定的参考价值。

我需要做类似的事情:

if (condition) 
    import something from 'something';

// ...
if (something) 
    something.doStuff();

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

我尝试使用System.import,如here所示,但我不知道System来自哪里。是不是最终被接受的ES6提案?该文章中“programmatic API”的链接将我转发给deprecated docs page

答案

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

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

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

这基本上是一个承诺。承诺的解决方案预计将有模块。该提案还具有其他功能,如多个动态导入,默认导入,js文件导入等。您可以找到有关dynamic imports here的更多信息。

另一答案

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

let something = null;
let other = null;

if (condition) 
    something = require('something');
    other = require('something').other;

if (something && other) 
    something.doStuff();
    other.doOtherStuff();

另一答案

你不能有条件地进口,但你可以做相反的事情:有条件地出口。这取决于您的使用案例,因此这项工作可能不适合您。

你可以做:

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

另一答案

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

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

我认为目的是尽可能地启用静态分析,并且条件导入的模块会破坏它。另外值得一提 - 我正在使用Babel,我猜测Babel不支持System,因为模块加载器API没有成为ES6标准。

另一答案

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

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]);
另一答案

在为我工作的eval中隐藏它,将它隐藏在静态分析器中......

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

另一答案

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

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

if(something) 
  something.doStuff();

另一答案

使用三元和require()s也可以实现有条件的进口:

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

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

另一答案

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

Dynamic Module Imports Example

具有导入和导出模块的基本知识。

JavaScript modules Github

Javascript Modules MDN

以上是关于如何有条件地导入ES6模块?的主要内容,如果未能解决你的问题,请参考以下文章

有条件地导入 python 类的片段

如何使用 ES6 模块导入来导入路径

如何有条件地将 C 代码片段编译到我的 Perl 模块?

如何使用 ES6 模块导入文件,并将其内容作为字符串读取?

模块中的条件导入

使用关键字“使用”有条件地导入类