简体   繁体   English

沿着es6模块生活

[英]iife along es6 module

I have a library that is basically an IIFE that sets a global variable, and clients are supposed to operate on said variable. 我有一个库,它基本上是一个设置全局变量的IIFE,客户端应该对所述变量进行操作。 So, in module.js , I have something like 所以,在module.js ,我有类似的东西

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

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

I want to make it compatible with ES6 modules, so that I could do 我想让它与ES6模块兼容,这样我才能做到

import * as theModule from 'module.js';

as well as 以及

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

How can that be accomplished? 怎么能实现呢? I remember some libraries that were that way (even AMD-compatible) but I don't even know what to search for. 我记得有些库是那种方式(甚至与AMD兼容),但我甚至不知道要搜索什么。

ES6 modules, IMHO, were inspired by the value of IIFEs, encapsulation being an important benefit. 恕我直言,ES24模块的灵感来自于IIFE的价值,封装是一项重要的好处。 So, refactoring an IIFE could be straightforward. 因此,重构IIFE可能很简单。

First you can remove the IIFE wrapper (you don't have to but, there's no benefit to keeping it, and you may have to be careful because the scope for the arguments you're passing in may differ). 首先,您可以删除IIFE包装器(您不必这样做,但保留它没有任何好处,您可能必须小心,因为您传入的参数的范围可能不同)。

If you know that the library is intended for the browser only AND you want to maintain backwards compatibility, then you can replace your root variable with window . 如果您知道该库仅用于浏览器并且您希望保持向后兼容性,那么您可以用window替换您的root变量。

The next challenge is to identify the public API and export it. 下一个挑战是识别公共API并将其导出。 So, say that some of the original API looks like this: 所以,假设一些原始API看起来像这样:

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

You'd export this function like this 你可以像这样导出这个函数

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

And, when you do 而且,当你这样做

import * as libFns from 'myLib'

libFns will act as a sort of namespace that will let you do, libFns将充当一种可以让你做的命名空间,

libFns.somePublicFn(...)

in the importing module. 在导入模块中。

And, like I mentioned above, if you want to also make these exports available globally, you'd have to hand-wire this yourself and do something like 而且,像我上面提到的,如果你想使全球范围内提供这些产品出口,你必须手工线这个自己,这样做

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

You need to not conflate the code you write with the code you provide to others: the latter is a tools question. 您不需要将您编写的代码与您提供给他人的代码混淆:后者是一个工具问题。

Write ES modules, then use something like this to provide something to your users they can easily consume via the method of their choice: commonJS, AMD, global, their choice with no more work on your part other than a build pipeline step. 写ES模块,然后使用类似这样提供的东西你的用户,他们可以通过自己选择的方法很容易消耗:CommonJS的,AMD,全球性的,他们的选择与比构建流水线步之外的其他部分没有更多的工作。

Remove the IIFE wrapper and export what you were assigning. 删除IIFE包装并导出您分配的内容。

Note about webpack: 关于webpack的注意事项:

Webpack uses an... ES2015-ish syntax for modules that doesn't actually work with eg <script type="module"> . Webpack使用... ES2015-ish语法用于实际上不能与例如<script type="module"> Since webpack is almost an industry-standard at this point, I would be remiss to not mention it. 由于webpack在这一点上几乎是一个行业标准,我不能不提它。 Unfortunately, it doesn't play all that great with the setup above. 不幸的是,它并没有在上面的设置中发挥出色。 As far as I know, that's still an open problem. 据我所知,这仍然是一个悬而未决的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM