在 ESM 之前,前端常用的模块规范有 AMD,CommonJS 以及 UMD,其中 AMD 是浏览器端的 JavaScript 模块规范,以 requireJS 为代表,CommonJS 主要用在 Node 中,是服务端 JavaScript 模块规范。UMD 则对二者进行了一个整合。
使用 AMD 规范
通过 requireJS 这个库,可以在浏览器上使用 AMD 规范来管理依赖。这里有一个简单的例子。
首先是 HTML 代码,通过 script
标签引入了 requireJS 库文件,其中 script
标签上的 data-main
属性是告诉 requireJS,项目的主文件是 main.js
,requireJS 将首先加载 main.js
文件。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script data-main="main" src="./require.js"></script>
<title>Document</title>
</head>
<body>
</body>
</html>
接下来看 main.js
文件的内容:
// 对 requireJS 进行配置
require.config({
paths:{
lib:"./lib",
}
})
// 使用 require 导入模块
require(["lib"],(lib) => {
lib.print();
})
main.js
中依赖了 lib
模块,lib
模块在 lib.js
中定义,其中 lib
模块又依赖了 help
模块,在 help.js
中定义。下面是 lib.js
和 help.js
的代码:
// 使用 define 定义模块
define(["help"],(help) => {
return {
print(){
console.log("Module Lib")
help.print();
}
}
})
// 使用 define 定义模块
define(() => {
const text = "Module Help";
return {
print(){
console.log(text)
}
}
})
下面是这个例子中的文件列表:
.
└── module
├── help.js
├── index.html
├── lib.js
├── main.js
└── require.js
在浏览器中打开 HTML 文件,我们看到控制台有如下输出:
Module Lib
Module Help
以上,就是借助 requireJS 使用 AMD 规范的基本用法。
使用 CommonJS 规范
CommonJS 是服务端的 JavaScript 模块规范,在使用 Node 时使用的频率非常高,这里就不多介绍了。
使用 UMD 规范
UMD 规范也叫做通用模块规范(Universal Module Definition),同时兼容了 AMD 规范和CommonJS 规范。这意味着 UMD 规范可以同时在浏览器和服务端上使用。(CommonJS 规范也可以在浏览器上使用,可以参考这篇文章)
下面我们使用 UMD 规范来定义前面提到的 lib
模块,新建一个 lib.umd.js
文件:
((root,factory) => {
// 如果存在 define 全局函数,就使用 AMD 规范
if(typeof define === "function"){
define(["help"],factory)
// 如果存在 exports 对象,就使用 CommonJS 规范
}else if(typeof exports === "object"){
module.exports = factory(require("./help"))
// 上述条件都不满足,尝试使用全局的方式定义模块
}else{
root.returnExprots = factory(root.help)
}
})(window,(help) => {
return {
print(){
console.log("Module Lib(UMD)")
help.print();
}
}
})
在使用 UMD 规范时,首先定义一个自执行函数,该函数接受一个 factory
工厂方法作为参数,和使用 requireJS 一样,factory
方法接受一系列的参数,这些参数就是模块所依赖的其他模块,factory
返回值就是我们要向外暴露出的模块。factory
方法会在其依赖的模块都被加载后调用。
在自执行函数的函数体中,对 AMD 规范 和 CommonJS 规范进行了兼容性的处理,根据所处的环境来使用不同的模块规范。
如果既没有采用 AMD 规范有没有采用 CommonJS 规范,将会尝试通过全局的方式定义模块。
接下来,修改 main.js
文件的配置项,将 lib
模块指向 lib.umd.js
:
// 对 requireJS 进行配置
require.config({
paths:{
lib:"./lib.umd",
}
})
// 使用 require 导入模块
require(["lib"],(lib) => {
lib.print();
})
在浏览器中重新打开 HTML 文件,控制台输出如下:
Module Lib(UMD)
Module Help
以上,我们就结合和 AMD 规范和 UMD 规范,实现了前端的模块化。使用 UMD 规范定义的 lib
库,既可以在浏览器使用(AMD),又可以在服务端使用(CommonJS)。
完。
网友评论