16、什么是模块化

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!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:立即执行函数,借助于函数作用域,使用“模块化”
也可以看做闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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实现

1
2
3
4
5
6
7
8
9
10
11
12
// 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 定义模块
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做兼容,类似下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(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、扩展协同方便性;
最终实现了一切皆模块,是前端工程化的基石。


16、什么是模块化
https://mrhzq.github.io/职业上一二事/前端面试/每日知识卡片/16、什么是模块化/
作者
黄智强
发布于
2024年2月3日
许可协议