js模块化介绍

什么是模块化

通常一个文件是一个模块,有自己的作用域,只对外暴露特定变量和函数

为什么使用模块化

  1. 代码复用
  2. 解决依赖关系, 利于维护
  3. 避免全局变量污染

JS模块化规范有哪些:

  • IIFE(早期): 立即执行的匿名函数, 就是一个模块, 匿名函数内部变量不会污染全局对象
  • CommonJS
  • ES6 Module
  • AMD
  • CMD

CommonJS

  • 主要实践者: Node
  • 包含四个环境变量: module exports require global
  • CommonJS是同步加载模块
  • 适合场景:
    • 服务端读取本地磁盘非常快, 所以很适合该规范
    • 而浏览器端受限网络, 更适合异步加载

ES6 Module

  • 主要由两个命令构成: export import
  • 编译时就引入模块代码, 而不是运行时加载
  • 无法实现条件加载, 可以实现静态分析

ES6 Module与CommonJS的差异

  1. CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。
  2. CommonJS模块是运行时加载,ES6模块是编译时加载(所以import存在变量提升)
    • 运行时加载: CommonJS模块就是对象(即module.exports属性)
    • 编译时加载: ES6模块不是对象,而是通过export命令显式指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出 值,而不是加载整个模块,这种加载称为“编译时加载”
  3. require支持动态加载, 而import不支持

AMD规范

  • 主要实践者: require.js
  • require.config()指定引用路径等
  • define()定义模块
  • require()加载模块

CMD规范

  • 主要实践者: sea.js
  • define()定义模块
  • use()加载模块

require.js和sea.js异同

  • 相同点:requirejs 和 seajs 都是异步加载模块的

  • 不同:

    1. requirejs 特点是依赖前置,指的是所有依赖提前加载完成
    2. seajs 特点是就近依赖,指的就是:什么时候用某个模块,那么就什么时候去加载这个模块

    但是实际使用中,sea.js也是提前加载完依赖模块, 才执行function,也就跟require.js没什么区别了