模块化的发展历程


一、模块化

1.1.什么是模块化

  • 模块划就是按照一定的规则把代码封装成若干的相互依赖的文件并进行组合
  • 每个模块内的数据都是私有的,只向外选择性的暴露一些方法和数据与外界进行数据通信

1.2.模块化的意义

  • 有利于代码分享、解耦以及复用
  • 团队并行开发
  • 避免命名冲突
  • 相互引用,按需加载

1.3. 模块化的发展史

  • 自执行函数
  • AMD (Asynchronous Module Definition)
    • AMD 推崇依赖前置,在定义模块的时候就要声明其依赖的模块
    • AMD规范则是非同步加载模块,需要定义回调define方式
  • CMD (Common Module Definition)
    • CMD 推崇就近依赖,只有在用到某个模块的时候再去 require
  • CommonJS (服务器端开发)
  • UMD (Universal Module Definition)
    • UMD 叫做通用模块定义规范(Universal Module Definition)可以通过运行时或者编译时让同一个代码模块在使用 CommonJs、CMD 甚至是 AMD 的项目中运行
  • ES6 Module (ESM,JS 官方标准模块定义方式)

1. 4 common.js 和 ES6 中模块引入的区别

目前浏览器端虽写法是以 esm 为主,但是各种前端工具转换为 cjs

在使用上的差别主要有:

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

  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口(静态编译)。

  • CommonJs 是单个值导出,ES6 Module 可以导出多个

  • CommonJs 是动态语法可以写在判断里,ES6 Module 静态语法只能写在顶层

  • CommonJsthis 是当前模块,ES6 Modulethisundefined

  • CommonJS是服务器端模块的规范,CommonJS规范加载模块是同步的

注意:

  • export {<变量>}这种方式一般称为 命名式导出 或者 具名导出,导出的是一个变量的引用
  • export default 这种方式称为 默认导出 或者 匿名导出,导出的是一个值。
// a.js
let x = 10
let y = 20
setTimeout(() => {
  x = 100
  y = 200
}, 100)
export { x }
export default y
// b.js
import { x } from "./a.js"
import y from "./a.js"
setTimeout(() => {
  console.log(x, y) // 100,20
}, 100)

二、实现

2.1 有依赖的自执行函数

  • 手工引入依赖
  • 依赖关系不明显
;(function (global) {
  function add(a, b) {
    return a + b
  }
  global.addModule = { add }
})(window)
;(function (global) {
  function minus(a, b) {
    return a - b
  }
  global.minusModule = { minus }
})(window)
;(function (global, addModule, minusModule) {
  global.mathModule = { add: addModule.add, minus: minusModule.minus }
})(window, addModule, minusModule)

console.log(mathModule.add(2, 2))
console.log(mathModule.minus(2, 2))

2.2 AMD

  • require.js

  • 前置依赖

    define(id?, dependencies?, factory);
let moduleFactory = {}
function define(name, factory) {
  moduleFactory[name] = factory
}
function require(dependencies, callback) {
  callback(...dependencies.map((dependency) => moduleFactory[dependency]()))
}

define("addModule", function () {
  function add(a, b) {
    return a + b
  }
  return {
    add,
  }
})
define("minusModule", function () {
  function minus(a, b) {
    return a - b
  }
  return {
    minus,
  }
})
require(["addModule", "minusModule"], function (addModule, minusModule) {
  console.log(addModule.add(1, 2), minusModule.minus(3, 4))
})

2.3. CMD

  • CMD 叫做通用模块定义规范(Common Module Defination )
  • seajs
let factories = {}
let modules = {}
function require(name) {
  if (modules[name]) {
    return modules[name]
  }
  let factory = factories[name]
  let exports = {}
  factory(require, exports)
  modules[name] = exports
  return exports
}
function define(name, factory) {
  factories[name] = factory
}
function use(name) {
  require(name)
}
define("addModule", function (require, exports) {
  exports.add = function (a, b) {
    return a + b
  }
})
define("minusModule", function (require, exports) {
  exports.minus = function (a, b) {
    return a - b
  }
})

define("index", function (require, exports) {
  var addModule = require("addModule")
  let result1 = addModule.add(1, 2)
  console.log(result1)
  var minusModule = require("minusModule")
  let result2 = minusModule.minus(1, 2)
  console.log(result2)
})
use("index")

文章作者: 高红翔
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 高红翔 !
  目录