沿ES6模块的Iife

时间:2019-02-08 15:05:43

标签: javascript es6-modules umd

我有一个基本上是IIFE的库,它设置了一个全局变量,并且客户端应该在该变量上进行操作。因此,在module.js中,我有一个类似

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

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

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

import * as theModule from 'module.js';

以及

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

那怎么实现?我记得有些库就是这种方式(甚至与AMD兼容),但我什至不知道要搜索什么。

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

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

编写ES模块,然后使用诸如this之类的东西向您的用户提供一些东西,他们可以通过自己选择的方法轻松使用它们:commonJS,AMD,global,他们的选择,除了您自己以外没有其他工作构建管道步骤。

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

关于webpack的注意事项:

Webpack对不实际使用的模块使用ES2015-ish语法,例如<script type="module">。由于此时webpack几乎是一种行业标准,因此我不提它就不提了。不幸的是,在上面的设置中,它并没有发挥出色。据我所知,这仍然是一个悬而未决的问题。