前端模块化学习笔记总结

120 阅读4分钟

image.png

文章概要

  • AMD
  • CMD
  • CommonJS
  • ES6 Module
  • UMD

AMD

由于通常应用在浏览器端,所以采用非同步的模式。

基本语法:

定义暴露模块:

// 定义没有依赖的模块
define(function(){
  return 模块
})

// 定义有依赖的模块
define(['module1','module2'],function(m1,m2){
  return 模块
})

引入使用模块:

require(['module1','module2'],function(m1,m2){
  使用 m1/m2
})

CMD

CMD也是应用于浏览器端,异步加载的。CMD规范整合了CommonJS和AMD规范的特点。

基本语法:

// 定义没有依赖的模块
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()
})

AMD与CMD的区别

// CMD 
define(function(require,exports,module){
  // 依赖就近书写
  var module1 = require('Module1')
  var result1 = module1.exec()
  module.exports = {
    result1: result1   
  }
})

// AMD
define(['Module1'],function(module1){
  var result1 = module1.exec()
  return {
    result1:result1
  }
})

区别为:

  1. 对依赖的处理:
  2. AMD推崇依赖前置,即通过依赖数组的方式提前声明当前模块的依赖;
  3. CMD推崇依赖就近,在编程需要用到的时候通过调用require方法动态导入;
  4. 在本模块的对外输出:
  5. AMD推崇通过返回值的方式对外输出;
  6. CMD推崇通过给module.exports赋值的方式对外输出;

CommonJS

Node 应用由模块组成,采用 CommonJS模块规范。每个文件就是一个模块,有自己的作用域。在一个文件里定义的变量、函数、类,都是私有的,对其他文件不可见。在服务器端,模块的加载是运行时同步加载的,在浏览器端,模块需要提前编译打包处理。

特点:

  • 所有代码都运行在模块作用域,不会污染全局作用域;
  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清楚缓存;
  • 模块加载的顺序,按照其在代码中出现的顺序;

基本语法:

// 暴露模块
module.exports = value

// 引入模块
var bar = require('./xxx')

Q:CommonJS暴露的模块到底是什么?

A: CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量时一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports 属性。

require方法用于加载模块文件。require方法的功能是,读入并执行一个javaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。

模块的加载机制:

输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。这点与ES6模块化有重大差异。

ES6 Module

ES模块与CommonJS模块的差异

  1. CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用;
  2. CommonJS 模块是运行时加载,ES6 模块是编译时输出接口;

UMD(Universal Module Definition)

是一种javascript通用模块定义规范,让你的模块能在javascript所有运行环境中发挥作用。要满足所有规范。

总结

  1. CommonJS规范主要用于服务端编程,加载模块是同步的,这并不适合在浏览器环境,因为同步意味着阻塞加载,浏览器资源是异步加载的,因此有了AMD CMD解决方案;
  2. AMD规范在浏览器环境中异步加载模块,而且可以并行加载多个模块。不过,AMD规范开发成本高,代码的阅读和书写比较困难,模块定义方式的语义不顺畅;
  3. CMD规范与AMD规范很类似,都用于浏览器编程,依赖就近,延迟执行,可以很容易在Node.js中运行;
  4. ES6 在语言标准的层面上,实现了模块的功能,而且实现的很简单,完全可以取代CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案;
  5. UMD 为同时满足CommonJS,AMD,CMD标准实现;