简体   繁体   中英

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. So, in module.js , I have something like

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

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

I want to make it compatible with ES6 modules, so that I could do

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.

ES6 modules, IMHO, were inspired by the value of IIFEs, encapsulation being an important benefit. So, refactoring an IIFE could be straightforward.

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).

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 .

The next challenge is to identify the public API and export it. So, say that some of the original API looks like this:

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.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.

Remove the IIFE wrapper and export what you were assigning.

Note about webpack:

Webpack uses an... ES2015-ish syntax for modules that doesn't actually work with eg <script type="module"> . Since webpack is almost an industry-standard at this point, I would be remiss to not mention it. Unfortunately, it doesn't play all that great with the setup above. As far as I know, that's still an open problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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