Search code examples
javascriptmoduleecmascript-5

JavaScript ES6 Modules: Avoid Polluting Global Namespace


Background

When importing modules in JavaScript, we pollute the global namespace with the imported module's name:

foo.js

export foo() {..};
export const bar = 3.14;

index.js

import { foo, bar } from './foo.js';

Question

In index.js, foo and bar live in the global namespace, right? So, let's say I publish this module and someone uses it in their HTML file, together with another script which also defines the variables foo and bar in the global namespace. Would we not have a collision then?

I guess this can be solved by wrapping everything within main.js in an IIFE. But, for some reason, ESLint complains about that, making me wonder if IIFEs isn't the preferred / recommended approach to protect the global namespace.

  1. Will the global namespace be polluted with foo and bar?
  2. If so, how should I avoid it?

Thank you.


Solution

  • When importing modules in JavaScript, we pollute the global namespace with the imported module's name

    No. Every module has its own module scope, in which all the imported bindings and top-level declarations live.

    In a plain ES6 environment with only ES6 modules, you almost never use the global scope - all module code is strict mode code so you really have to make an effort to create a variable on the global object.

    Module bundlers typically alleviate that by allowing you to declare a few exports to become global variables in the bundled script, so that you can easily access them in your page when using other scripts as well.