As your JavaScript application grows, keeping all code in a single file becomes unmanageable. The JavaScript Module System (ES Modules) is the modern standard for breaking code into separate, reusable files. Modules ensure that code is isolated, preventing conflicts and making it easier to maintain and share code.
The Problem with the Global Scope
Before modules, all variables and functions defined in script files were placed in the global scope. This meant two separate files could accidentally use the same variable name, leading to conflicts and bugs. Modules solve this by giving each file its own, private scope.
The ES Module System
ES Modules use the import
and export
keywords to define which code should be shared between files.
1. How to Use Modules in HTML
To tell the browser that a script file should be treated as a module and use the import
/export
syntax, you must add type="module"
to the <script>
tag.
HTML
<script src="main.js" type="module"></script>
2. Exporting Code
In a module file (e.g., utils.js
), you can export functions, variables, or classes.
Named Exports
You can export multiple things from a file using named exports.
JavaScript
// utils.js
// Export a constant
export const PI = 3.14159;
// Export a function
export function calculateArea(radius) {
return PI * radius * radius;
}
// Export a class
export class UserProfile {
constructor(name) {
this.name = name;
}
}
Default Exports (One per file)
You can define a single default export per module. This is typically the main component or function the module provides.
JavaScript
// auth.js
function login(username, password) {
// login logic
return { token: 'abc' };
}
// The consuming file can name this whatever they want
export default login;
3. Importing Code
In a consuming file (e.g., main.js
), you use the import
keyword.
Importing Named Exports
You must use the exact names and include them in curly braces {}
.
JavaScript
// main.js - importing from utils.js
import { PI, calculateArea, UserProfile } from './utils.js';
console.log(calculateArea(5)); // Uses the imported function
const user = new UserProfile('Jane');
Importing Default Exports
You can choose any name for the default import (no curly braces {}
).
JavaScript
// main.js - importing from auth.js
import authenticate from './auth.js'; // 'authenticate' could be 'loginFn'
const token = authenticate('user', 'pass');
console.log('Token:', token);
Importing Everything (Namespace Import)
You can import all named exports as a single object (a namespace).
JavaScript
// main.js
import * as Utils from './utils.js';
console.log(Utils.PI);
const area = Utils.calculateArea(10);