【问题标题】:iife along es6 module沿着 es6 模块的 iife
【发布时间】:2019-02-08 15:05:43
【问题描述】:

我有一个库,它基本上是一个设置全局变量的 IIFE,客户端应该对所述变量进行操作。所以,在module.js,我有类似的东西

window.myModule = (function(){
    ...

    return {
        foo: foo,
        bar: bar
    }
})();

我想让它与 ES6 模块兼容,这样我就可以做到

import * as theModule from 'module.js';

还有

<script src="module.js"></script>

如何实现?我记得有些库是这样的(甚至与 AMD 兼容),但我什至不知道要搜索什么。

【问题讨论】:

标签: javascript es6-modules umd


【解决方案1】:

ES6 模块,恕我直言,受到 IIFE 价值的启发,封装是一个重要的好处。因此,重构 IIFE 可能很简单。

首先,您可以删除 IIFE 包装器(您不必这样做,但保留它没有任何好处,而且您可能必须小心,因为您传入的参数的范围可能不同)。

如果您知道该库仅适用于浏览器并且您希望保持向后兼容性,那么您可以将您的root 变量替换为window

下一个挑战是识别公共 API 并将其导出。所以,假设一些原始 API 看起来像这样:

root.MyLib.prototype.somePublicFn = function () {...}

你会像这样导出这个函数

export let somePublicFn = function () {...}

而且,当你这样做时

import * as libFns from 'myLib'

libFns 将充当一种命名空间,让您可以这样做,

libFns.somePublicFn(...)

在导入模块中。

而且,就像我上面提到的,如果您想在全球范围内提供这些导出,您必须自己手动连接并执行类似的操作

const api = {
  somePublicFn
  ...
}
root.MyLib.prototype = Object.assign(root.MyLib.prototype, api)

【讨论】:

    【解决方案2】:

    您不需要将您编写的代码与您提供给他人的代码混为一谈:后者是一个工具问题。

    编写 ES 模块,然后使用 this 之类的东西为您的用户提供一些他们可以通过他们选择的方法轻松使用的东西:commonJS、AMD、全局,他们的选择,除了构建之外您无需再做任何工作管道步骤。

    删除 IIFE 包装器并导出您分配的内容。

    关于 webpack 的注意事项:

    Webpack 使用... ES2015-ish 语法来处理实际上无法使用的模块,例如&lt;script type="module"&gt;。由于 webpack 在这一点上几乎是一个行业标准,我将不提它。不幸的是,上面的设置并不能很好地发挥作用。据我所知,这仍然是一个悬而未决的问题。

    【讨论】:

    • 我不想使用另一个构建步骤。我记得前段时间检查过一个以if 开头的模块,检查环境是否支持 ES6 模块,但我不记得下一步该做什么了。
    • @user405205​​4 这实际上是不可能的。 ES 6 模块是静态链接的。在条件(或顶级以外的任何地方)中有导入或导出语句是语法错误。有一个基于 Promise 的动态导入提案,但尚未标准化。这是构建步骤或继续编写 IIFE。
    猜你喜欢
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多