模块化演进

69 阅读2分钟

定义

模块化在编程中是指将程序分解成独立、可重用的模块,每个模块负责特定的功能。这样做的好处是提高代码的可维护性、可读性和复用性。

演进历程

  1. 原始阶段(无模块化)

    问题:变量污染,依赖混乱

    临时方案

    var App = {};
    App.utils = { /* ... */ };
    
    // IIFE闭包隔离
    (function(window) {
      window.myModule = { /* ... */ };
    })(window);
    
  2. CommonJS(CJS)

    特点:同步加载、动态导入

    局限:无法直接用于浏览器(同步阻塞)

    语法

    // 导出
    module.exports = { foo };
    exports.bar = bar;
    
    // 导入
    const mod = require('./mod');
    ```
    ```
    
  3. AMD

    场景:浏览器异步加载

    特点:前置依赖声明、异步加载

    局限:语法冗余、不符合开发直觉

    语法

    define(['dep1', 'dep2'], (dep1, dep2) => {
      return { /* 模块内容 */ };
    });
    
    require(['module'], (module) => { /* ... */ });
    ```
    ```
    
  4. CMD/sea.js

    改进:就近依赖声明(按需加载)

    语法

      const dep = require('./dep');
      exports.value = dep.process();
    });
    
  5. UMD(通用模块)

    目标:兼容CJS/AMD/全局变量

    实现

    (function(root, factory) {
      if (typeof exports === 'object') {  // CJS
        module.exports = factory();
      } else if (typeof define === 'function') {  // AMD
        define(factory);
      } else {  // 全局
        root.MyLib = factory();
      }
    })(this, () => ({ /* 模块逻辑 */ }));
    ```
    ```
    
  6. ES Modules(ESM)

    优势

    • 静态分析(编译时优化)
    • 浏览器原生支持
    • 支持循环引用(有特殊规则)

    语法

    // 导出
    export const foo = 1;
    export default function() {};
    
    // 导入
    import { foo } from './mod';
    import('dynamic-module').then(...);
    ```
    ```
    

关键演进对比

阶段加载方式环境依赖处理典型代表
无模块化全局加载浏览器无管理IIFE
CommonJS同步Node.js动态解析Node modules
AMD异步浏览器前置声明RequireJS
ESM静态全平台编译时分析现代浏览器

模块化的演进始终围绕工程效率运行时性能展开,理解其发展脉络有助于在项目中合理选择模块化方案,并有效解决兼容性、性能优化等实际问题。