25. JavaScript Modules
What you will learn
- Why we split code into modules
- How to
exportandimport - 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.jsin 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
exportandimport, with named or default exports. - Load with
type="module"and serve the files from a web server.