ES2015 中的条件导出

Conditional export in ES2015

假设您正在开发一个 polyfill,如果 class 已经存在于浏览器中,您不想填充它。这在 ES6 中如何实现?以下无效,因为 exports 不是语句:

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

如果上述条件的计算结果为 false,则导入脚本应内置浏览器。

export 语法必须在模块的顶级范围内,因为您要声明存在的导出。您可以自由地有条件地为它们分配一个值,例如

export let Foo = global.Foo;

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

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

ES6模块应该这样处理:

export let Foo;

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

对于独立于平台的解决方案(this 在转译代码中可能不等于 global)window 可以替换为

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

这利用了以这种方式设计的 ES6 模块的绑定功能 to handle cyclic dependencies and explained greatly here

上面的代码transpiles to

...
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 值是有条件的。

以上方法对我的 Webpack 不太适用。有条件地退出导致 Webpack 警告,在缩小之前将包大小增加了 20KB。

Webpack 插件进行了优化,可用于生产构建。以下代码在不增加包大小的情况下对我有用。

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

上述条件要求并未增加生产构建的包大小。