我有一个基本上是IIFE的库,它设置了一个全局变量,并且客户端应该在该变量上进行操作。因此,在module.js
中,我有一个类似
window.myModule = (function(){
...
return {
foo: foo,
bar: bar
}
})();
我想使其与ES6模块兼容,这样我就可以做到
import * as theModule from 'module.js';
以及
<script src="module.js"></script>
那怎么实现?我记得有些库就是这种方式(甚至与AMD兼容),但我什至不知道要搜索什么。
答案 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对不实际使用的模块使用ES2015-ish语法,例如<script type="module">
。由于此时webpack几乎是一种行业标准,因此我不提它就不提了。不幸的是,在上面的设置中,它并没有发挥出色。据我所知,这仍然是一个悬而未决的问题。