28

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

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

如果上述条件评估为false,则导入脚本应该内置浏览器。

4

3 回答 3

22

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 模块的绑定特性,该特性以这种方式设计以处理循环依赖关系,并在此处进行了详细解释。

上面的代码转换为

...
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绑定到此导出的值是有条件的。

于 2016-09-20T00:56:16.753 回答
12

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

export let Foo = global.Foo;

if (typeof Foo === 'undefined'){
    Foo = class { ... }
}
于 2016-09-20T00:45:14.180 回答
1

上述方法对我使用 Webpack 效果不佳。有条件地退出会导致 Webpack 警告,这会在缩小之前将包大小增加 20KB。

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

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

上述条件要求不会增加生产构建的捆绑包大小。

于 2019-02-18T07:14:54.367 回答