25. JavaScript Modules

What you will learn

  • Why we split code into modules
  • How to export and import
  • Named and default exports
  • How to load a module in HTML

Why modules?

As a program grows, one giant file becomes hard to read and full of name clashes. A module is a JavaScript file that keeps its variables private and shares only what you choose. Other files then import what they need.

The Try it Yourself editor cannot load separate files, so the examples in this lesson are for reading and copying. Try them on your own computer with a few small files.

Named exports

Put export in front of anything you want to share.

math.js file

export const TAX_RATE = 0.1;

export function add(a, b) {
  return a + b;
}

export function withTax(price) {
  return price + price * TAX_RATE;
}

const secret = "not shared";   // stays private to this file

Import them by name, inside curly braces:

main.js file

import { add, withTax } from "./math.js";

console.log(add(2, 3));        // 5
console.log(withTax(100));     // 110

The path must start with ./ or ../ and include the .js ending.

Default exports

A file can have one default export. The importer chooses the name, with no curly braces.

greet.js file

export default function greet(name) {
  return `Hello, ${name}!`;
}

main.js file

import greet from "./greet.js";

console.log(greet("Sam"));   // Hello, Sam!
Kind Export Import
Named export const x = 1; import { x } from "./file.js";
Default export default value; import anyName from "./file.js";
Rename import { add as sum } from "./math.js";
Everything import * as math from "./math.js";

Loading a module in HTML

Use type="module" on the script that starts your program.

HTML file

<script type="module" src="main.js"></script>

What type=”module” changes

  • It defers automatically, so the page is ready before the script runs.
  • Code runs in strict mode.
  • Variables are private to the module and are not added to the global scope. Other plain scripts cannot see them.
  • Each file is loaded once, however many files import it.

You need a web server

Browsers block modules opened straight from your computer (a file:// address). Run a local server, for example the VS Code extension Live Server, or your LocalWP site. On a real website it just works.

Dynamic import

Load a module only when it is needed with import(), which returns a promise. This keeps the first page load small.

Syntax

button.addEventListener("click", async () => {
  const { add } = await import("./math.js");
  console.log(add(1, 2));
});

Organising a project

Folder structure

project/
  index.html
  js/
    main.js        (starts the program)
    math.js        (calculations)
    dom.js         (helpers that change the page)

Give each file one clear job, export only what others need, and keep main.js short.

Common mistakes

  • Forgetting type="module", which gives “Cannot use import statement outside a module”.
  • Leaving off ./ or the .js in the path.
  • Opening the page as file:// instead of through a server.
  • Importing a default export with curly braces, or a named one without them.
  • Circular imports, where two files import each other.

Exercise

Write a file text.js that exports a named function shout(text), returning the text in capital letters with ! on the end. Then write the line in main.js that imports it.

Show solution
// text.js
export function shout(text) {
  return text.toUpperCase() + "!";
}

// main.js
import { shout } from "./text.js";
console.log(shout("hello"));   // HELLO!

Knowledge check

1. Which keyword shares something from a module?

export

2. Which attribute lets a script use import?

type="module"

3. Why do modules need a web server?

Browsers block module loading from file:// addresses for security.

Summary

  • Modules split code into files with private variables.
  • Use export and import, with named or default exports.
  • Load with type="module" and serve the files from a web server.
Scroll to Top