一、为什么需要模块化?
你是否遇到过这些情况:
- 全局变量命名冲突(两个
user
变量打架) - 代码分散在多个文件难以维护
- 想复用某个功能却不知道怎么组织代码
ES6 模块系统让代码像搭积木一样简单!今天就教你用 import
和 export
管理代码。
二、模块的基本操作
1. 导出方式一:具名导出
场景:将数学工具函数单独封装
// math.js
export function add(a, b) {
return a + b;
}
export const PI = 3.14;
2. 导出方式二:默认导出
每个文件最多一个
// logger.js
const log = (msg) => console.log(`[LOG] ${msg}`);
export default log; // 导出默认函数
三、模块的导入方法
1. 导入具名成员
import { add, PI } from './math.js';
console.log(add(2, 3)); // 5
console.log(PI); // 3.14
2. 导入默认导出
import log from './logger.js';
log('初始化完成'); // [LOG] 初始化完成
3. 混合导入
import log, { add } from './math.js'; // 注意:默认导出在前
四、模块 vs 全局变量对比🧩
需求:实现一个学生管理系统
ES5 全局变量写法(污染全局)
// student.js
var students = [];
function addStudent(name) {
students.push(name);
}
// 其他文件直接使用全局变量 students
ES6 模块写法(安全隔离)
// student.js
const students = [];
export function addStudent(name) {
students.push(name);
}
// 其他文件必须通过导入才能使用
五、模块的优势🚀
特性 | ES5 全局变量 | ES6 模块 |
---|---|---|
作用域 | 污染全局 | 完全封闭 |
复用性 | 手动复制代码 | 直接 import |
依赖管理 | 需按顺序加载文件 | 自动解析依赖关系 |
性能 | 可能重复执行代码 | 只执行一次 |
六、新手常见误区⚠️
-
路径问题:
- 必须明确相对路径(
./
代表当前目录) - 不能省略扩展名(
import './math'
❌ →import './math.js' ✅
)
- 必须明确相对路径(
-
模块作用域:
- 模块内的变量默认不暴露到全局
- 需要显式
export
才能被外部访问
-
浏览器兼容性:
- 直接在 HTML 中使用需加
<script type="module">
- 生产环境建议用打包工具(Webpack/Rollup)
- 直接在 HTML 中使用需加
七、案例:构建一个天气查询模块🌈
目录结构:
1. 具名导出 API 模块
// api.js
const API_KEY = 'your-key';
export function fetchWeather(city) {
return fetch(`https://api.weather.com/${city}?key=${API_KEY}`);
}
2. 默认导出格式化函数
// format.js
export default (data) => {
return `${data.city} 今日天气:${data.condition}`;
};
3. 主文件导入使用
// main.js
import { fetchWeather } from './api.js';
import format from './format.js';
fetchWeather('上海')
.then(data => format(data))
.then(msg => console.log(msg));
总结
模块系统是现代 JavaScript 开发的基石,通过 import/export
可以:
- 清晰划分功能模块
- 避免全局变量污染
- 方便代码复用与维护