ES Modules: Default Export và Named Exports
JavaScript Modules (ES6) cho phép chia sẻ code giữa các file. Có 2 loại export:
| Đặc điểm | Default Export | Named Exports |
|---|---|---|
| Số lượng/file | Chỉ 1 | Nhiều (không giới hạn) |
| Tên khi import | Tự đặt tên bất kỳ | Phải trùng tên export (hoặc dùng as) |
| Cú pháp export | export default ... | export const ... hoặc export { name } |
| Cú pháp import | import myName from '...' | import { name } from '...' |
| Renaming | Tự động khi import | import { name as newName } |
Ví dụ hoàn chỉnh (3 file)
1. sample.js - Module nguồn
// sample.js
// Default export - chỉ 1 per file
export default function testImport() {
return 'Module testImport đã được import';
}
// Named exports - có thể nhiều
export function tellTime() {
return new Date();
}
export const VERSION = '1.0.0';
export const PI = 3.14159;
2. script.js - Import và sử dụng
// script.js
import defaultExport from "./sample.js"; // Default: tên tùy ý
import { tellTime, VERSION, PI as PI_VALUE } from "./sample.js"; // Named: tên chính xác hoặc alias
let resultEle = document.querySelector('.result');
document.querySelector('.Btn').addEventListener('click', () => {
resultEle.innerHTML = defaultExport() + "
";
resultEle.innerHTML += "Time: " + tellTime() + "
";
resultEle.innerHTML += "Version: " + VERSION + "
";
resultEle.innerHTML += "PI: " + PI_VALUE;
});
3. index.html - HTML chính (type="module")
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ES Modules</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
.result { font-size: 18px; font-weight: 500; color: rebeccapurple; font-family: monospace; }
button { padding: 8px 16px; cursor: pointer; }
</style>
</head>
<body>
<h1>Default Export vs Named Export</h1>
<div class="result"></div>
<button class="Btn">THỰC HIỆN IMPORT</button>
<h3>Nhấn nút để chạy hàm import dưới dạng default và named</h3>
<script src="script.js" type="module"></script>
</body>
</html>
Kết hợp Default và Named
// Export cùng lúc
export default function main() { ... }
export function helper1() { ... }
export function helper2() { ... }
// Import cả hai
import main, { helper1, helper2 as h2 } from './module.js';
Re-export (Tái xuất)
// index.js - barrel file
export { default as MyComponent } from './MyComponent';
export * from './utils'; // Re-export tất cả named exports
export { helper } from './helpers';
Lưu ý quan trọng
- Modules **mặc định strict mode**.
- Modules **không chia sẻ scope toàn cục** (mỗi file là module riêng).
- Cần chạy trên **HTTP server** (không mở file:// trực tiếp do CORS).
type="module"trên script tag tự động defer.- Dynamic import:
const module = await import('./module.js')(xem bài Dynamic Imports).
CommonJS vs ES Modules (Node.js)
// CommonJS (Node.js cũ)
module.exports = { foo: 1 }; // hoặc exports.foo = 1
const { foo } = require('./module');
// ES Modules (Node.js mới, file .mjs hoặc "type": "module" trong package.json)
export const foo = 1;
import { foo } from './module.js';