Accessing globals inside JS modules (ESM)
Tags: javascript, todayilearned
Published: 2020-01-03 12:23:10

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](https://github.com/microsoft) to help solve really tricky problems, and [share our stories](https://www.microsoft.com/developerblog) 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](https://overlayed.app) - it helps broadcasters interact with their viewers in new ways, using overlays. Under the hood, Overlayed is powered by user-defined modules (using [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)), that export React components. You can learn more about that, [here](https://dev.to/bengreenier/introducing-overlayed-streamer-overlays-powered-by-react-17ja) - 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);

```

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')
```

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.](https://thepracticaldev.s3.amazonaws.com/i/8vetwjkau8qm3yes0uad.PNG)
> 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.](https://thepracticaldev.s3.amazonaws.com/i/6f8wbabhlwpb93hej1or.PNG)
> 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](https://unsplash.com/@kelli_mcclintock?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/box?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)