了解前端模块化,commonJS/AMD/CMD/ES6

258 阅读3分钟

什么是模块化

  • 模块化可以提高代码复用率,方便进行代码的管理
  • 模块化主要是用来抽离公共代码,私有作用域,避免变量冲突等
  • 目前流行的js模块化规范有CommonJS、AMD、CMD以及ES6的模块系统

区别

  • Node.js采取CommonJS规范,因为是服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,可以采取同步加载模块

  • 浏览器端一般采用AMD规范,浏览器环境要从服务器端加载模块,这时就必须采用异步模式,出的早,可以指定回调函数

  • CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。CMD规范整合了CommonJS和AMD规范的特点

  • RequireJS是一个工具库,主要用于客户端的模块管理。它的模块管理遵守AMD规范,RequireJS的基本思想是,通过define方法,将代码定义为模块;通过require方法,实现代码的模块加载

  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用

  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口

commonJS

// 暴露模块:module.exports = value或exports.xxx = value
var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

// 引入模块:require(模块名或模块文件路径)
var example = require('./example.js')
console.log(example.x) // 5
console.log(example.addX(1)) // 6

特点

  • 私有模块作用域,不会污染全局作用域

  • 加载模块是同步的,按照其在代码中出现的顺序

  • 模块可以多次加载,有缓存。第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存

  • 模块的加载机制,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。多个模块取值会影响。

AMD

// AMD是异步加载模块,允许指定回调函数// 定义暴露模块: 没有依赖的模块
define(function(){
   return 模块
})// 定义暴露模块: 有依赖的模块
define(['module1', 'module2'], function(m1, m2){
   return 模块
})
// 引入使用模块:
require(['module1', 'module2'], function(m1, m2){
   使用m1/m2
})

CMD

// CMD模块使用时才会加载执行
// 定义暴露模块:没有依赖的模块
define(function(require, exports, module){
  exports.xxx = value
  module.exports = value
})
// 定义暴露模块:有依赖的模块
define(function(require, exports, module){
  //引入依赖模块(同步)
  var module2 = require('./module2')
  //引入依赖模块(异步)
    require.async('./module3', function (m3) {
    })
  //暴露模块
  exports.xxx = value
})

//引入使用模块:
define(function (require) {
  var m1 = require('./module1')
  var m4 = require('./module4')
  m1.show()
  m4.show()
})

ES6模块化

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

// export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
// 定义模块 math.js
var basicNum = 0;
var add = function (a, b) {
    return a + b;
};
export { basicNum, add };
// 引用模块
import { basicNum, add } from './math';
function test(ele) {
    ele.textContent = add(99 + basicNum);
}