如何有条件导入ES6模块?

2020/10/16 22:01 · javascript ·  · 0评论

我需要做类似的事情:

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

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

我尝试使用此处System.import所示的方法,但是我不知道从哪里来。这是没有最终被接受的ES6提案吗?该文章中指向“编程API”的链接将我转至不推荐使用的docs页面System

现在,ECMA确实有动态进口建议。这是在第3阶段。这也可以作为babel-preset使用

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

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

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

如果需要,可以使用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”,因为在混合面板的情况下,它需要初始化。

看起来答案是,到目前为止,您还不能这样做。

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

我认为其目的是尽可能地启用静态分析,而有条件导入的模块可以打破这种情况。另外值得一提的是-我使用的是Babel,我猜这System是Babel不支持的,因为模块加载器API尚未成为ES6标准。

require()这是一种在运行时导入某些模块的方法,它同样可以进行静态分析,就像import与字符串文字路径一起使用一样捆绑程序需要此功能来为捆绑程序选择依赖项。

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

对于具有完整静态分析支持的动态模块解析,首先在indexer(index.js)中建立索引模块,然后在主机模块中导入indexer。

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

如果使用动态导入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(...);
}

在评估中使它模糊不清对我有用,将其隐藏在静态分析器中...

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

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

动态模块导入示例

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

JavaScript模块Github

Javascript模块MDN

不,你不能!

但是,碰到这个问题应该使您重新考虑如何组织代码。

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

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

本文地址:http://javascript.askforanswer.com/ruheyoutiaojiandaorues6mokuai.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!