16、什么是模块化?

67 阅读1分钟

一种管理代码的方式,核心是将相关的代码弄成独立的单元(模块)。

发展历程

script 标签:最开始通过在 HTML 里面引入不同的 script 标签,强行“模块化”

<!DOCTYPE html>
<htlm lang='zh'>
	<head>
    <meta charse="utf=-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>xx</title>
  </head>
  <body>
    <div>xxx</div>
    <script src="https://xxxx/jquery.js"></script>
    <script src="./main.js"></script>
    <script src="./tool.js"></script>
    <!-- <script src="./*.js"></script> -->
  </body>
</htlm>

缺点:变量会产生冲突


IIFE:立即执行函数,借助于函数作用域,使用“模块化”

也可以看做闭包

const moduleA = (function() {
  let count = 0
  const addCount = () => ++count
  const getCount = () => count

  return {
    getCount,
    addCount
  }
})()

moduleA.addCount()
moduleA.getCount() // 1

const moduleB = (function() {
  let count = 0
  const addCount = () => count + 2
  const getCount = () => count

  return {
    getCount,
    addCount
  }
})()

moduleB.addCount()
moduleB.getCount() // 2

CJS(CommonJS) :支持node端的模块同步加载规范,通过requireexports实现

// moduleA.js
let count = 0
const addCount = () => count + 1
const getCount = () => count

exports.addCount = addCount
exports.getCount = getCount

// main.js
const moduleA = require('./moduleA.js')
moduleA.addCount()
moduleA.getCount() // 1

缺点:只支持同步,容易阻塞


AMD(Async Module Define) :支持浏览器端的模块异步加载规范,著名产物require.js

// 定义模块
define('moduleA', ['deps1', 'deps2'], function(deps1, deps2) {
  let count = 0
  const addCount = () => count + 1
  const getCount = () => count

  return {
    getCount,
    addCount
  }
})

// 使用模块
require(['moduleA'], function(moduleA) {
  moduleA.addCount()
  moduleA.getCount() // 1
})

缺点:语法繁琐


UMD(Universal Module Define) :一种兼容前面模块的加载规范

本质是利用 IIFE 做兼容,类似下面的代码

(function(root, factory) {
  const moduleName= factory.name
  if(define && typeof define === 'function') {
    // 兼容 AMD
    define(moduleName, [], factory)
  } else if(typeof exports === 'object') {
    // 兼容 CJS
    exports[moduleName] = factory()
  } else {
    // 挂载到全局
    root[moduleName] = factory()
  }
})(this, function moduleA() {
  let count = 0
  const addCount = () => count + 1
  const getCount = () => count

  return {
    getCount,
    addCount
  }
})

ESM(ES6 Module) :ECMA 支持的模块加载机制,通过importexport实现

这也是我们目前最常用的方式,支持异步


模块化的目的:1、隔离代码逻辑;2、扩展协同方便性;

最终实现了一切皆模块,是前端工程化的基石。