ES2015中的条件导出

36

假设你正在开发一个polyfill,并且不想在浏览器中重新定义一个已经存在的类,那么如何在ES6中实现?下面的代码是无效的,因为exports不是一个语句:

假设您正在开发一个polyfill,不希望在浏览器中对已经存在的类进行模拟。如何在ES6中实现此功能?以下代码是无效的,因为exports不是语句:

if (typeof Foo === 'undefined') {
  export class Foo { ... }
}

如果上述条件求值结果为 false,那么导入脚本应该获取浏览器内置的内容。


1
如果有人尝试导入该值且条件为假,您期望导入的值是什么? - loganfsmyth
3个回答

30

export应该是静态的。对于条件导出,可以使用CommonJS模块和exports

对于ES6模块,应该这样处理:

export let Foo;

if (window.Foo === undefined) {
  Foo = class Foo { ... }
} else {
  Foo = window.Foo;
}

对于跨平台的解决方案(this在转译后的代码中可能不等同于全局),window可以被替换为

const root = (() => eval)()('this');
if (root.Foo === undefined) {
...

这利用了 ES6 模块的绑定特性,该特性是为了处理循环依赖而设计的,详见 这里,并在 这里 进行了详细解释。

```html

以上的代码... var Foo = exports.Foo = void 0; if (window.Foo === undefined) { exports.Foo = Foo = function Foo() { _classCallCheck(this, Foo); }; } else { exports.Foo = Foo = window.Foo; }

在这种情况下,导出不是有条件的,但是绑定到此导出的Foo值是有条件的。


13

export 语法必须处于模块的顶层作用域,因为您在声明哪些导出存在。不过,您可以有条件地为它们分配值,例如:

export let Foo = global.Foo;

if (typeof Foo === 'undefined'){
    Foo = class { ... }
}

2

对于Webpack,上述方法并不适用。有条件地退出会导致Webpack警告,这将在缩小之前增加20KB的捆绑大小。

Webpack插件具有优化功能,可用于生产构建。以下代码适用于我,而不会增加捆绑大小。

最初的回答:

let comp = null;
if (process.env.NODE_ENV) {
  comp = require('./MyDevComp').default;
}

上述条件式不会增加生产环境的打包大小。

注:原回答为"Original Answer"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接