Skip to main content

JavaScript Modules

JavaScript Modules

Written by Published

A module is a file that can export values for other files to import.

Before modules, every script shared one global scope, and names easily collided.

A module has its own scope; nothing is visible outside it unless exported.

Example

Example

javascript

// The examples below simulate two files with a plain object,
// since import/export only works between real separate files.
const mathUtils = {
  double(n) {
    return n * 2;
  }
};

console.log(mathUtils.double(5));

The output is 10.

The complete page at the end of this lesson shows the real file syntax.

Why Modules Exist

Each module file has its own private scope.

export makes something available to other files.

import brings an exported value into another file.

Syntax

Syntax

javascript

// math.js
export function double(n) { return n * 2; }

// main.js
import { double } from "./math.js";

The file extension is required in the import path in the browser.

The Old Way

Every plain script shared the same global scope.

Two scripts declaring the same variable name would clash.

Example

Example

javascript

var total = 5;
var total = 10;

console.log(total);

In separate module files, each total would be private and safe.

A Module's Scope Is Private

Modelling it with a function shows the same isolation a real module gives.

Example

Example

javascript

function mathModule() {
  const total = 5;
  return { total: total };
}

const otherModule = { total: 10 };

console.log(mathModule().total + " and " + otherModule.total);

Each keeps its own total, exactly as separate module files would.

Only Exported Names Are Visible

Everything else stays private to the file.

Example

Example

javascript

const mathUtils = (function () {
  const secretHelper = 2;
  return {
    double: function (n) {
      return n * secretHelper;
    }
  };
})();

console.log(mathUtils.double(5));
console.log(typeof mathUtils.secretHelper);

secretHelper was never exported, so it cannot be reached from outside.

Modules Run Once

However many files import the same module, its code runs only the first time.

Every importer shares the same result.

Example

Example

javascript

let runCount = 0;

function loadModule() {
  runCount++;
  return { value: 42 };
}

const first = loadModule();
const second = first;

console.log(runCount);
console.log(first === second);

A real module behaves the same way: it is cached after the first import.

Modules Are Strict by Default

You do not need "use strict"; modules always run in strict mode.

An accidental global assignment throws instead of silently creating a global.

Example

Example

javascript

function strictAssign() {
  "use strict";
  let message;
  try {
    undeclaredName = 5;
  } catch (error) {
    message = error.name;
  }
  return message;
}

console.log(strictAssign());

A real module gives this behaviour automatically.

Complete Example

Complete Example

html

<!-- /samples/math.js -->
<script type="module">
  export function double(n) {
    return n * 2;
  }
</script>

<!-- main.js, loaded as a module -->
<script type="module">
  import { double } from "/samples/math.js";

  document.getElementById("out").textContent = double(5);
</script>

<!-- In the HTML: -->
<!-- <script type="module" src="main.js"></script> -->

<p id="out"></p>

Try It Yourself

The Try It Editor runs a single file, so real import/export needs two files on a server.

Try the simulated version:

Run the opening example above, which behaves the same way without needing separate files.

Important Points

  • A module is a file with its own private scope.
  • export makes a name available outside the file.
  • import brings it into another file.
  • A module's code runs once, however many times it is imported.
  • Modules are always in strict mode.

Conclusion

Modules solved the shared global scope problem that plain scripts always had.

The examples here simulate that isolation with plain objects and functions.

The next lessons cover the exact export and import syntax.