想象一下你正在写一个大型项目, 所有代码都堆在一个文件里: var utils = {...};var api = {...};var componentA = {...};var componentB = {...};
function doSomething() {    }
这种写法有几个致命问题: 
- 命名冲突: 变量和函数都在全局作用域,容易覆盖 
- 依赖混乱:不知道代码执行前需要加载哪些依赖 
- 难以维护: 代码组织像意大利面条,牵一发而动全身 
 
 
模块化就是为了解决这些问题而生的! 它让我们可以: 
- 将代码拆分成独立的小文件(模块) 
- 明确声明依赖关系 
- 避免污染全局命名空间 
- 方便代码复用和维护 
二、CommonJS
CommonJS 是 Node.js 采用的模块系统, 语法非常简单: function add(a, b) {    return a + b;}
function subtract(a, b) {    return a - b;}
module.exports = {    add,    subtract};
exports.add = add;exports.subtract = subtract;
const math = require('./math.js');
console.log(math.add(2, 3)); console.log(math.subtract(5, 2)); 
- 同步加载: 模块在 require 时同步加载并执行. 
- 缓存机制: 模块首次加载后会被缓存, 后续 require 直接返回缓存. 
- 值拷贝: 导出的是值的拷贝(对于原始类型), 修改不会影响原模块. 
三、ES Modules
ES Modules(简称 ESM)是 ECMAScript 2015(ES6)引入的官方模块系统, 现在已经被现代浏览器和 Node.js 支持. 
export function add(a, b) {    return a + b;}
export function subtract(a, b) {    return a - b;}
export default {    add,    subtract};
import { add, subtract } from './math.js';
import math from './math.js';
import math, { add } from './math.js';
import * as math from './math.js';
- 静态分析: ESM 的 import/export 必须在顶层作用域, 可以被静态分析 
- 动态绑定: ESM 导出的是值的引用(活的绑定), 修改会影响所有导入 
- 异步加载: ESM 在浏览器中是异步加载的 
export let count = 0;
export function increment() {    count++;}
import { count, increment } from './counter.js';
console.log(count); increment();console.log(count); 
<script src="app.js"></script>
<script type="module" src="app.js"></script>
关键区别: 
四、按需加载
静态导入(import ... from ...)必须在模块顶层, 但有时候我们需要按需加载: import('./math.js').then(math => {    console.log(math.add(2, 3));});
async function calculate() {    const math = await import('./math.js');    console.log(math.add(2, 3));}
if (user.isAdmin) {    import('./admin.js').then(...);}
<link rel="modulepreload" href="critical-module.js">
Promise.all([    import('./moduleA.js'),    import('./moduleB.js')]).then(([moduleA, moduleB]) => {    });
阅读原文:原文链接
该文章在 2025/7/21 10:33:09 编辑过