Converting closure to es6 module

I am using a javascript build environment that supports es6 modules ( using es6-module-transpiler ), so you can just import stuff across different files.

I now have a third party library that I would like to "import".

The library fills in its functions as follows:

(function () {/*...*/}).call(this);

      

It would be safe to omit the closure and convert it to:

export default function () {/* ... */};

      

Or is there a better way?

Thanks in advance!

+3


source to share


2 answers


In the source code you show, calls an anonymous function that makes some sense should define a global variable, whereas the second piece of code you show just exports the function, which is completely different.

For purposes of discussion, let's assume the source code defines a global value:

// my-third-party-module.js
(function() {
  let myVar = 22;
  window.MyThirdPartyModule = { log: function() { console.log(myVar); } };
}.call(this);

      

and you use it like this:

// app.js
MyThirdPartyModule.log();

      

You can rewrite this as

// my-third-party-module.js
let myVar = 22;
export default { log: function() { console.log(myVar); } };

// app.js
import MyThirdPartyModule from `my-third-party-module';
MyThirdPartyModule.log();

      

Note that we have moved the variable myVar

that was local to the anonymous function at the top level of the module.



However, depending on your preference, rather than exporting a LOB, which is a kind of pre-modular mentality, you can export its API separately:

// my-third-party-module.js
let myVar = 22;
export function log { console.log(myVar); }

// app.js
import {log} from `my-third-party-module';
log();

      

or if you prefer

// app.js
import * as MyThirdPartyModule from `my-third-party-module';
MyThirdPartyModule.log();

      

However, all of these approaches assume that you can and want to edit the source of the third party library. If not, you can write a small piece of glue code like

// my-third-party-module-interface.js
import 'my-third-party-module';    // This will run the module.
export default MyThirdPartyModule; // Export the global it defined.

// app.js
import MyThirdPartyModule from 'my-third-party-module-interface';

      

If you'd rather re-export the individual APIs, you can extend the glue to re-export each one:

// my-third-party-module-interface.js
import 'my-third-party-module';    // This will run the module.

const {log, otherAPI, ...} = MyThirdPartyModule;
export {log, otherAPI, ...};

// app.js
import {log} from 'my-third-party-module-interface';

      

+1


source


Converting legacy dependencies is still a problem. And the horrible workflow they use makes things a lot harder, prefixing the actual code with the browser and webpack silliness.

So what to do? Existentially the library is only guaranteed to bring in a global window, but it's unclear and weird. And everyone is a little different.



So let legacy just do what it should do for you, but wrapped in a module so you can import it rather than using a script tag:

https://medium.com/@backspaces/es6-modules-part-2-libs-wrap-em-up-8715e116d690

0


source







All Articles