The ECMAScript Module (ESM) syntax revolves around two fundamental keywords: export (exposing variables, functions, and classes to external files) and import (consuming those exposed bindings in other files).
1. Named Exports and Imports
Named exports allow you to share multiple identifiers from a single module by name.
Exporting:
JavaScript
1// mathUtils.js
2
3// Option A: Inline export
4exportconstPI=3.14159;
5
6exportfunctionadd(a, b){
7return a + b;
8}
9
10exportfunctionsubtract(a, b){
11return a - b;
12}
13
14// Option B: Grouped export declaration at bottom
15// export { PI, add, subtract };
Importing:
JavaScript
1// app.js
2import{PI, add }from'./mathUtils.js';
3
4console.log(add(10,5));// 15
5console.log(PI);// 3.14159
2. Default Exports
Each module can have at most onedefault export. Default exports are useful when a module's primary purpose is to deliver a single class, component, or configuration:
JavaScript
1// User.js
2exportdefaultclassUser{
3constructor(name){
4this.name = name;
5}
6}
Importing Default Exports:
When importing a default export, you do not use curly braces {} and can choose any name:
JavaScript
1// consumer.js
2import UserAccount from'./User.js';// Any alias name works!
3
4const admin =newUserAccount('Sarah');
3. Renaming with the as Keyword
To avoid naming collisions between imported modules, use as to alias identifiers:
JavaScript
1// Renaming during import:
2import{ render as renderCanvas }from'./canvas.js';
3import{ render as renderDOM }from'./domRenderer.js';
4
5renderCanvas();
6renderDOM();
7
8// Renaming during export:
9const secretKey ='XYZ_123';
10export{ secretKey as apiKey };
4. Namespace Import: import * as
To import all named exports from a module under a single namespace object:
JavaScript
1import*as MathService from'./mathUtils.js';
2
3console.log(MathService.PI);
4console.log(MathService.add(20,30));
5console.log(MathService.subtract(50,10));
Output
1 mathUtils.js exports:
2 ├── PI: 3.14159
3 ├── add()
4 └── subtract()
5 │
6 ▼
7 import * as MathService
8 │
9 ▼
10 MathService.add(20, 30)
5. Dynamic Imports: import()
While standard import statements must be static and at the top of the file, the dynamic import('path') function loads modules asynchronously on demand (code-splitting):