• 前端模块化是一种标准,不是一种实现
  • 将复杂程序根据规范拆分成若干个模块,一个模块包括输入和输出
  • 模块的内部实现是私有的,对外暴露接口与其他模块通信

    进化过程

  • 文件划分方式: 全局命名冲突问题

  • 命名空间方式:外部能修改模块内部
  • IIFE+闭包方式:模块间依赖不好管理

    CommonJS

  • Node.js 默认模块化规范,每个文件都是一个模块,有自己的作用域

  • Node中 CJS 模块采用同步加载方式
  • 通过 require 加载模块,通过module.exportseports输出模块
  • 所有代码都运行在模块作用域,不会污染全局作用域
  • 模块可以多次加载,第一次加载时会运行模块,模块输出结果会被缓存,再次被加载时,会从缓存结果中直接读取模块输出结果。
  • 模块加载的顺序,按照其在代码中的出现的顺序。
  • 模块输出的值是值的拷贝,类似 IIFE 方案中的内部变量。

AMD/CMD

  • AMD规范采用异步加载模块,require.js是AMD的一个实现
  • CMD整合了 CJS 和 AMD 的优点,sea.js 是CMD的一个实现
  • AMD和CMD的最大问题都是没有通过语法升级解决模块化

    ES Module

  • ESModule设计理念是希望在编译时就确定模块依赖关系及输入输出

  • CJS 和 AMD 必须在运行时才能确定依赖和输入、输出
  • ESM通过 import 加载模块化,通过 export 输出模块

    对比

  • CJS 模块输出的是值的拷贝,ES6 模块输出的是值的引用

  • CJS 模块是运行时加载,ES6 模块是编译时输出接口
  • CJS 是单个值导出,ES6 模块可以导出多个
  • CJS 模块为同步加载,ES6 支持异步加载
  • CJS 模块的this是当前模块,ES6 模块的this是undefined

参考资料