chunhuigao/web-studybook

AMD、CMD、UMD、ES6

Opened this issue · 0 comments

模块化之前

最初 js 是这样写的

<script>
  function main(){' '}
  {
    // doing
  }
  main();
</script>

这样写的 js 随着代码增加会带来几个问题:

  • main 函数变量在全局作用域
  • 代码复用
  • 代码可维护性

解决上述问题

命名空间

var namespace = {
  main: function () {
    //doing
  },
};
namespace.main();

闭包 IIFE

var utils = function () {
  var namespace = {
    main: function () {
      //doing
    },
  };
  return namespace;
};
utils.main();

缺点

需要开发人员知道引用顺序,在使用命名空间或者闭包中的方法时要提前引用

服务端模块化

2009 年 node 中实现了 Common.js

// tool.js

function main() {
  console.log('main');
}
module.exports = main;

// index.js
var tool = require('./tool.js');
tool.main();

同步读取硬盘中资源,服务端读取硬盘中资源几乎没什么延时;但是浏览器如果同步读取资源。创建 http -> 加载 -> 返回资源。这个延时就比较长了。可能会引起浏览器假死。所以浏览器中中使用异步模块加载

浏览器模块化

浏览器中中使用异步模块加载

AMD

  • AMD 是异步模块定义;
  • AMD 采用异步方式加载模块。模块加载不影响后面语句执行。
  • AMD 所有依赖这个模块的语句都定义在这个回调函数中,等模块加载完成之后再回调这个函数。
  • AMD 通过 define 函数定义模块,通过 require 函数引用模块
    • define 函数第一个参数是数组,数组中是依赖模块,第二个参数是模块的返回值
    • require 函数第一个参数是数组,数组中是依赖模块,第二个参数是个回调,回调的参数是依赖的输出
  • 被依赖的文件需要早于依赖文件的加载就可以通过 require 解决
  • 在使用 require 的时候需要提前加载所有依赖
  • 所以被称为依赖前置
// tool.js

define([], function (require, factory) {
  'use strict';
  return {
    main: function () {
      console.log(111);
    },
  };
});

// index.js
require(['./tool.js'], function (tool) {
  tool.main();
});

CMD

  • 就近依赖
  • 在需要的时候 require
// tool.js
function main() {
  console.log('main');
}
module.exports = main;

// index.js
define(function (require, exports) {
  const tool = require('./tool.js');
  tool.main;
});

UMD

  • 通用模块定义
  • 写了一段代码,但是想在浏览器中和服务端中同时使用
  • UMD 就是帮助判断环境是使用 AMD 还是使用 Common.js 的方式定义模块,以上都不是,挂载到全局

ES6

  • import 导入 export 导出
  • Common.js 输出的是值的拷贝,ES6 输出的是值的引用
  • Common.js 是运行时加载,ES6 模块是编译事输出接口