DEV Community

Cover image for Accessing globals inside JS modules (ESM)
Ben Greenier
Ben Greenier

Posted on

Accessing globals inside JS modules (ESM)

Hi! I’m Ben Greenier — I’m an engineer at Microsoft working to create awesome open source projects with our partners. We get to create software to help solve really tricky problems, and share our stories as we go. This means that as part of my job I get to play with lots of new technologies, learn how to use them, and help other folks do the same.

Lately I've been working on a browser app called Overlayed - it helps broadcasters interact with their viewers in new ways, using overlays. Under the hood, Overlayed is powered by user-defined modules (using ESM), that export React components. You can learn more about that, here - but it's not what this post is about.

While working on getting things ready to import remote modules, I've been investigating replacing shared dependencies with a single version. For instance, since all remote modules will depend on React, I want to load React only once, and allow the modules to reference that single version.

As far as I could tell, this should just work, but I couldn't find any documentation that explicitly stated this. So, after a bit of googling around, I built a quick test.

Testing

To be sure this worked as expected, I created a quick test using a locally served "module" and JSFiddle to do the import. I tested with both Chrome and Firefox, and saw the expected results! 🎉

Here's the module code I used:

"use strict";

// notify that our esm bundle loaded
console.log("loaded");

// see if we have a react global
console.log(React);

Enter fullscreen mode Exit fullscreen mode

And the loader code (Note: React is imported by JSFiddle, so we don't need any code to do that):

// validate React is set
console.log(React)

// load our esm bundle
import('http://localhost:5000/test.js')
Enter fullscreen mode Exit fullscreen mode

And here's the results:

A screenshot of the firefox test, running successfully in the browser. In the image you can see JSFiddle, the browser console, and the expected output.

In Firefox, everything looks great!

A screenshot of the chrome test, running successfully in the browser. In the image you can see JSFiddle, the browser console, and the expected output.

In Chrome, everything looks great!

As you can see, the test is pretty simple - just a JSFiddle that loads React, and runs our import, and a locally served module, that logs loaded when it loads, and prints the React value from inside the module. Given that the React object both at the parent level and inside the module look the same, I'm happy to conclude this works great.

In conclusion

Globals (that is - things defined in the environment from which import will run) "just work" inside modules (the code inside the module, that import is running for us). That's the take-away. 😁

Thanks for reading,

💙🌈
-Ben

P.S: Header photo by Kelli McClintock on Unsplash

Discussion (0)