# requireJS
首先看下目录结构,我们需要使用 requireJS 搭建以下结构的应用 :
:-: ![](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/%E6%88%AA%E5%9B%BE/QQ%E6%88%AA%E5%9B%BE20180328103514.png)
## 引入 requireJS
在入口文件 index.html 中引入 requireJS,使用 `data-main` 定义入口文件。
```html
<script src="./require.js" data-main="./main"></script>
```
## config
使用 `require.config` 对 requireJS 进行基础配置。
其中 :
(1)baseUrl:模块默认加载路径;
(2)paths:自定义模块加载路径;
(3)shim:定义模块之间的依赖关系。
比如在 `main.js` 中 :
```js
require.config({
'baseUrl': './js/',
'paths': {
'jquery': '../lib/jquery-3.3.1.min'
}
}
```
以上代码进行了基本的 requireJS 配置,其中 baseUrl 将默认加载目录设置在 js 目录下,paths 中的依赖都将相对于 baseUrl 进行配置。
## require
使用 `require` 对加载的文件进行引用,如使用 jquery,在 `main.js` 中 : :
```js
require(['jquery'], ($) => {
$('body').css({'background-color':'#0f0'})
})
```
## define
使用 `define` 自定义要导出的模块,比如在 `test.js` 中 :
```js
define(['jquery'], () => {
return {
changeBgColor () {
$('body').css({'background-color':'#f00'})
},
changeTextSize () {
$('body').css({'font-size':'20px'})
}
}
})
```
这里定义了一个自定义模块,define 的第一参数为依赖项,第二参数为回调函数,在里面使用 return 导出需要导出的模块。
使用自定义模块也很容易,在 `main.js` 中 :
```js
require.config({
'baseUrl': './js/',
'paths': {
'jquery': '../lib/jquery-3.3.1.min',
'test': 'test'
}
})
require(['jquery', 'test'], ($, test) => {
$('#bgBtn').on('click', () => {
test.changeBgColor()
})
$('#textBtn').on('click', () => {
test.changeTextSize()
})
})
```
注意到,paths 中的路径都是基于 baseUrl 的,并不需要带 js 后缀。
在 `index.html` 中 :
```html
<div>
<div id="text">Hello world</div>
<div>
<button id="bgBtn">改变颜色</button>
<button id="textBtn">改变字体大小</button>
<button id="colorBtn">改变字体颜色</button>
<button id="resetBtn">恢复字体颜色</button>
<button id="boldBtn">改变字体粗细</button>
</div>
</div>
```
## 在 shim 中指定依赖
以上 `test.js` 中,明确指定了其依赖,也可以不在自定义模块中指定依赖,而使用配置项指定依赖。
比如 `util.js` :
```js
define([], function() {
return {
changeTextColor () {
$('#text').css({'color':'#fff'})
}
}
})
```
也可省略第一参数 :
```js
define(function() {
return {
changeTextColor () {
$('#text').css({'color':'#fff'})
}
}
})
```
此时,在 `main.js` 中 :
```js
require.config({
'baseUrl': './js/',
'paths': {
'jquery': '../lib/jquery-3.3.1.min',
'util': 'util'
},
'shim': {
'util': {
'deps' : ['jquery']
}
}
})
require(['jquery', 'util'], ($, util) => {
$('#colorBtn').on('click', () => {
util.changeTextColor()
})
})
```
可以看到,在 `shim` 中使用了 `deps` 指定依赖,其实也可以不指定,只需要在 `require` 中前置加载 jquery 依赖即可。
## 针对非 AMD 模块
针对非 AMD 模块,requireJS 也提供了加载机制,只需要在 shim 中指定 export 即可。
比如 `exp.js` :
```js
function resetTextColor () {
$('#text').css({'color':'#000'})
}
```
此时在 `main.js` 中
```js
require.config({
'baseUrl': './js/',
'paths': {
'jquery': '../lib/jquery-3.3.1.min'
},
'shim': {
'exp': {
'export': 'resetTextColor'
}
}
})
require(['jquery', 'exp'], ($, exp) => {
$('#resetBtn').on('click', () => {
resetTextColor()
})
})
```
可以看到,在 shim 中制定了 exp 文件的输出模块,在 require 里面引用之,可直接调用其方法。
### 导出多模块
使用 export 只能指定导出一个模块,但如果需要导出多个模块,则需要使用 init 方法。
如改写 `exp.js` :
```js
function resetTextColor () {
$('#text').css({'color':'#000'})
}
const changeTextWeight = () => {
$('#text').css({'font-weight':'bold'})
}
```
在 `main.js` 中
```js
require.config({
'baseUrl': './js/',
'paths': {
'jquery': '../lib/jquery-3.3.1.min'
},
'shim': {
'exp': {
'init': function(){
return {
'resetTextColor': resetTextColor, // 注意这里不需要加引号
'changeTextWeight': changeTextWeight
}
}
}
}
})
require(['jquery', 'exp'], ($, exp) => {
$('#resetBtn').on('click', () => {
exp.resetTextColor()
})
$('#boldBtn').on('click', () => {
exp.changeTextWeight()
})
})
```
注意,跟 export 不同,在调用的时候需要使用 exp 调用。
## 加载 css
可以使用 `css.js` 加载 css 文件,在 shim 中配置即可,如 :
```js
require.config({
'baseUrl': './js/',
'paths': {
'jquery': '../lib/jquery-3.3.1.min',
'util': 'util',
'css': '../lib/css'
},
'shim': {
'util': {
'deps' : ['jquery', 'css!../css/style.css']
}
}
})
```
案例地址: http://xiaoyulive.oss-cn-beijing.aliyuncs.com/date/2018-03-28/require.js.zip
## 总结
最后总结下RequireJs的原理:
(1)我们在使用requireJS时,都会把所有的js交给requireJS来管理,也就是我们的页面上只引入一个require.js,把data-main指向我们的main.js。
(2)通过我们在main.js里面定义的require方法或者define方法,requireJS会把这些依赖和回调方法都用一个数据结构保存起来。
(3)当页面加载时,requireJS会根据这些依赖预先把需要的js通过document.createElement的方法引入到dom中,这样,被引入dom中的script便会运行。
(4)由于我们依赖的js也是要按照requireJS的规范来写的,所以他们也会有define或者require方法,同样类似第二步这样循环向上查找依赖,同样会把他们村起来。
(5)当我们的js里需要用到依赖所返回的结果时(通常是一个key value类型的object, requireJS 便会把之前那个保存回调方法的数据结构里面的方法拿出来并且运行,然后把结果给需要依赖的方法。
- Web 开发笔记
- 从输入 URL 到页面加载完成的过程中都发生了什么事情?
- 从浏览器接收url到开启网络请求线程
- 开启网络线程到发出一个完整的http请求
- 从服务器接收到请求到对应后台接收到请求
- 后台和前台的http交互
- http的缓存
- 解析页面流程
- HTML解析,构建DOM
- CSS解析,构建CSSOM
- 资源外链的下载
- CSS的可视化格式模型
- 包含块(Containing Block)
- 控制框(Controlling Box)
- BFC(Block Formatting Context)
- IFC(Inline Formatting Context)
- 其它
- JS引擎解析过程
- JS的解释阶段
- JS的预处理阶段
- JS的执行阶段
- 回收机制
- 参考资料
- JavaScript模块化编程
- AMD
- requireJS
- CommonJS
- UMD
- ES6模块
- 参考资料
- 使用 JavaScript 实现一门编程语言
- 如何使用 JavaScript 实现一门编程语言(1) —— 前言
- 如何使用 JavaScript 实现一门编程语言(2) —— 编写一个解析器
- 如何使用 JavaScript 实现一门编程语言(3) —— Input stream
- 如何使用 JavaScript 实现一门编程语言(4) —— Token stream
- 如何使用 JavaScript 实现一门编程语言(5) —— AST
- 如何使用 JavaScript 实现一门编程语言(6) —— Interpreter
- 完整代码
- 参考资料
- 前端布局概论
- 参考资料
- Windows 笔记
- 错误解决
- win10应用商店无法登录提示0x80070426解决方法
- 使用技巧
- 设置 Hyper-V 和 VMware 共存
- Powershell
- WSL