模块化

74 阅读3分钟

AMD(Asynchromous Module Definition - 异步模块定义)

AMD是由RequireJS提出的一种模块化规范,它主要用于浏览器环境,在加载依赖模块时使用异步方式。AMD使用define函数来定义模块,使用 require 函数来加载模块。

//  定义没有依赖的模块
define(function(){
  return {模块}
});
// 定义有依赖的模块
define(["module1","module2"],function(m1,m2){
  return {模块}
});
require(["module1","module2"],function(m1,m2){
  使用m1/m2
});

CMD(Common Module Definition - 公共模块定义

CMD是由 SeaJS 提出的一种模块化规范,与AMD类似,CMD也是用于浏览器环境的模块化,模块的加载是异步的。不同之处在于 CMD 强调就近依赖,模块的加载是按需执行的,模块使用时才会加载执行。CMD 使用 define 函数来定义模块,使用 require 函数来加载模块。

//  定义没有依赖的模块
define(function (require, exports, module) {
  exports.XXX = value
  module.exports = value
});

// 定义有依赖的模块
define(function (require, exports, module) {
  // 引入依赖模块(同步)
  var module = require("./module")
  // 引入依赖模块(异步)
  require.asyc("./module1",function(m1){
  })
  // 暴露模块
  exports.XXX = value
});
define(function(require){
  var m1 = require("./module1")
  var m4 = require("./module4")
  m1.show()
  m4.show()
})

CommonJS

是一种模块化规范,主要用于服务器端开发(如 Node.js)。CommonJS规范通过 module.exports 导出模块,通过 require 函数加载模块。CommonJS 模块是同步加载的,这使得它在服务器端开发中非常方便。

在服务器端:模块的加载是运行时同步加载的

在浏览器端:模块需要提前编译打包处理 (浏览器端打包工具browserify)

//file1.js
exports.foo = function ()  {
  console.log("file1 foo")
}
exports.bar = function ()  {
  console.log("file1 bar")
}
//file2.js
module.exports ={
  msg:"module",
  foo(){
    console.log(this.msg);
  }
};
//file3.js
module.exports = function () {
    console.log("file3");
};
//app.js
var f1 = require('./js/file1');
f1.foo()
f1.bar()
var f2 = require('./js/file2');
f2.foo()
var f3 = require('./js/file3');
f3()

CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,
加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS
规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD CMD
解决方案。

UMD(Universal Module Definition - 通用模块定义)

是一种通用的模块化规范,旨在兼容不同的环境。UMD可以同时支持 AMD、CommonJS和全局变量的方式来导入和导出模块。

UMD是AMD和CommonJS的一个集合。AMD是浏览器优先,异步加载;CommonJS是服务器优先,同步加载。

既然要通用,怎么办呢?那就先判断是否支持node.js的模块,存在就使用node.js;再判断是否支持AMD(define是否存在),存在则使用AMD的方式加载。这就是所谓的UMD。

((root, factory) => {
  if (typeof define === 'function' && define.amd) {
    //AMD
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    //CommonJS
    var $ = requie('jquery');
    module.exports = factory($);
  } else {
    //都不是,浏览器全局定义
    root.testModule = factory(root.jQuery);
  }
})(this, ($) => {
  //do something...  这里是真正的函数体
});

es6 module(ECMAScript Modules)

是 ECMAScript 提供的官方模块化规范,从 ECMAScript 6 (ES6)开始引入。ESM 使用 import 和 export 关键字来导入和导出模块。ESM 支持静态分析,可以在编译时进行模块依赖的静态解析,提供更好的性能和可靠性。

安装插件

import XX from 'XX';
let year = 1994;
export default { year };

AMD 和 CMD 主要用于浏览器环境,强调异步加载。CommonJS 主要用于服务器端开发,采用同步加载。UMD 是通用的模块化规范。 ESM 是官方标准的模块化规范,具有静态分析和更好的性能