写在前面

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。目前,主要有两个Javascript库实现了AMD规范:require.jscurl.js。这里介绍 require.js。既然是模块,就涉及到两个通用的问题:1. 模块如何定义。2. 模块如何加载。

定义模块

require.js 中,定义一个模块的方式为:

define(callback)
// or
define([...modules], callback)

可以看出,在引入了 require.js 之后,全局提供了一个 define 函数,用于模块的定义。当 define 函数只接收到一个参数时,该参数为该模块的回调函数,在模块被加载时调用,函数的返回值即作为该模块的导出值。当 define 函数接收到两个参数时,第一个参数为该模块的依赖数组,第二个函数为该模块的回调函数,函数的参数依次为依赖数组的每一项。函数的返回值为该模块的导出值。

由模块定义的方式可以看出,define 函数并未提供定义模块名字的位置,那怎么唯一定义这个模块的名字呢?引用这个模块时的名字是什么呢?答案是文件名。

require.js要求,每个模块是一个单独的js文件。

加载模块

在 require.js 中,加载一个模块的方式为:

require([...modules], callback)

require 函数的第一个参数为要加载的模块,第二个函数为回调函数,在前面的模块加载完成后会调用回调函数,并将加载的模块的返回值依次传递给回调函数。

示例

下面以在浏览器项目中引用 require.js 为例展示其用法。项目结构如下:

1⃣️ 浏览器中引入 require.js

需要用 data-main 属性指明 require.js 的入文件,即主程序。

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Amd test</title>
</head>
<body>
    <script data-main="js/main.js" src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.min.js"></script>
</body>
</html>

2⃣️ 定义 a 模块和 b 模块

// a.js
define(function() {
    return {
        sayHi: function() {
            console.log('我是 A 模块!');
        }
    }
})

// b.js
define(['a'], function(a) {
    return {
        sayHi: function() {
            console.log('我是 B 模块!');
            a.sayHi()
        }
    }
})

3⃣️ 定义主模块,main.js

模块名即为文件名,当文件名不加后缀js的时候,文件路径默认与main.js在同一个目录。当文件名加后缀js的时候,文件路径默认为项目根目录。(这种现象为实践得到)

// main.js
require(['a', 'b'], function(a, b) {
    a.sayHi()
    b.sayHi()
})

在浏览器运行如下:

参考文章

Javascript模块化编程(一):模块的写法
Javascript模块化编程(二):AMD规范
Javascript模块化编程(三):require.js的用法


LoveVin
91 声望2 粉丝

技术改变世界,阅读塑造人生


引用和评论

0 条评论