Modules
As programs grow, keeping everything in one file becomes unmanageable. Modules let you split code into files, each exporting what others may use.
Exporting
In math.js:
// named exports: as many as you like
export const PI = 3.14159;
export function area(r) {
return PI * r * r;
}
export function circumference(r) {
return 2 * PI * r;
}Importing
In app.js:
import { area, circumference } from "./math.js";
console.log(area(2));
console.log(circumference(2));Names in { } must match the exported names. You can rename them, or import everything:
import { area as circleArea } from "./math.js";
import * as geometry from "./math.js";
console.log(circleArea(3), geometry.PI);Default exports
A module can have one default export, typically its main thing:
// user.js
export default class User {
constructor(name) { this.name = name; }
}// app.js: a default import can take any name, without braces
import User from "./user.js";
const u = new User("Asha");React components are usually default exports: export default function App() {...}.
Modules have their own scope
Variables declared in a module are private to it unless exported, so two modules can both have a count variable without clashing. Modules also run in strict mode automatically, and run only once however many files import them.
In the browser
Mark the script as a module, and it can use import:
<script type="module" src="app.js"></script>CodeMIRAI itself is built this way: the page loads app.js as a module, which imports store.js, badges.js and others.
Dynamic import
import() loads a module on demand and returns a promise, which keeps the first page load small:
button.addEventListener("click", async () => {
const { openEditor } = await import("./editor.js");
openEditor();
});That's how CodeMIRAI's lessons load the full code editor only when you press Edit.
Packages
Third-party code from npm is imported the same way, by package name (with a bundler such as Vite), or straight from a CDN in the browser:
import confetti from "https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.3/+esm";