Web/11-Node.js/JavaScript模块化:AMD.md
2021-07-29 11:08:52 +08:00

213 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: JavaScript模块化AMD
publish: true
---
<ArticleTopAd></ArticleTopAd>
## AMD的基本语法
### AMD的概念
**AMD**Asynchronous Module Definition异步模块定义AMD专门用于浏览器端模块的加载是异步的
[**AMD规范**](https://github.com/amdjs/amdjs-api):是 **[RequireJS](http://requirejs.org/)** 在推广过程中对模块化定义的规范化产出。
RequireJS一个基于AMD规范实现的模块化开发解决方案
### 暴露模块的方式
**定义没有依赖的模块**参数只有一个 function
```javascript
define(function () {
return 模块
})
```
**定义有依赖的模块**参数有两个模块名function
```javascript
//定义有依赖的模块:第一个参数为数组
define(['module1', 'module2'], function (m1, m2) {
return 模块
})
```
代码解释
- 第一个参数必须是数组里面存放的是需要依赖的其他的模块
- 第二个参数是function里面带了形参 m1 m2分别代表了 module1 module2这个形参的作用是前面依赖的模块一旦声明了就可以一一对应地注入到 function中去从而在 function 内部使用依赖的模块这种方式称之为**显式声明依赖注入**
### 引入模块的方式
在主模块中引入其他的模块
```javascript
//在主模块中引入其他的模块
require(['module1', 'module2'], function (m1, m2) {
使用m1 / m2
})
```
### RequireJS是AMD的实现
- <http://www.requirejs.org/>
- <http://www.ruanyifeng.com/blog/2012/11/require_js.html>
## RequireJS的使用举例自定义模块
### 1创建项目结构
在工程文件中新建如下目录
```
js
| libs
| modules
| alerter.js
| dataService.js
| main.js
index.html
```
所有的代码写完之后项目结构如下
![](http://img.smyhvae.com/20180411_1331.png)
### 2下载require.js并导入
- 官网: <http://requirejs.org/docs/download.html>
- GitHub<https://github.com/requirejs/requirejs>
在官网下载`require.js`文件
![](http://img.smyhvae.com/20180411_1127.png)
然后将`require.js`文件拷贝到项目的`js/libs/`目录中
这样的话就导入成功了
### 3自定义模块
1dataService.js
```javascript
//定义没有依赖的模块
define(function () {
let name = '我是 dataService.js中的内容';
function getName() {
return name;
}
//暴露模块
return { getName };
});
```
这模块没有依赖
2alerter.js
```javascript
//定义有依赖的模块
define(['myDataService'], function (dataService) {
let msg = '我是 aleter.js中的内容';
function showMsg() {
console.log(dataService.getName()); //调用了 myDataService 模块中的内容
console.log(msg);
}
//暴露模块
return { showMsg };
});
```
这个模块依赖了`myDataService`这个模块模块名是我自己起的稍后我们会在main.js中做映射`myDataService`这个名字和`dataService.js`文件关联起来
3main.js
> 这个是主模块
```javascript
requirejs.config({
//baseUrl: 'js/', //基本路径
paths: { //配置路径
myDataService: './modules/dataService',
myAlerter: './modules/alerter'
}
});
requirejs(['myAlerter'], function (alerter) {
alerter.showMsg();
})();
```
这个模块依赖了`myAlerter`这个模块模块名是我自己起的并且我们在文件的上方做了映射`myAlerter`这个名字和`alerter.js`文件关联了起来
我们来讲一下最上方的几行代码`requirejs.config`里的内容的意思
- 我们可以看到文件3依赖了文件2文件2依赖了文件1
- `paths`里做的就是映射将键`myDataService`和文件`dataService.js`进行关联将键`myAlerter`和文件`alerter.js`进行关联
另外再讲一下注释里的`baseUrl`的用法如果没有这个注释那么`paths`里的路径是从**当前这个文件**main.js的角度出发的如果加了一行`baseUrl`表明它是 paths 里所有路径的最开头的部分`baseUrl`的路径是从**项目的根目录**的角度出发的
4index.html
这个是入口文件
```html
<!DOCTYPE html>
<html lang="en">
<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">
<title>Document</title>
</head>
<body>
<!-- 先通过 src 引入 require.js 文件,然后通过 data-main 引入主模块main.js -->
<script data-main="js/main.js" src="js/libs/require.js"></script>
</body>
</html>
```
注意上面的代码中我们直接通过`src`属性引入`requre.js `文件一旦这个文件发挥作用了会去找`data-main`属性里的指向它正好指向的是主模块
有了上面这种引入的方式我们就不用再老土地引入多个`<script>`标签了
运行 index.html打印结果如下
![](http://img.smyhvae.com/20180411_1740.png)
项目源码[2018-04-11-RequireJSDemo](https://download.csdn.net/download/smyhvae/10341963)