由于CommonJS
采用适合服务器端的同步加载方式,这种方式不适合天生异步的浏览器端。在这种形势下,AMD
(Asynchronous Module Definition
,异步模块定义)应运而生。而require.js
正是AMD
规范下的产物,因此,我们可以直观地从require.js
入手分析AMD
。
require.js
这是RequireJS官方下载链接,我本次测试使用的是2.3.5
版本。
加载require.js
使用RequireJS后,我们不用在html中手动添加蛮蛮多的script标签了,通过模块依赖的方式,RequireJS会自动创建script标签,也使得模块间依赖关系的管理变得更加方便。首先,需要在html中引入require.js,并通过data-main属性指定入口js文件
1 | <script src="./js/amd/require-2.3.5.js" data-main="./js/amd/main" defer async></script> |
定义模块
我们先不关注main.js的实现,先来看看在RequireJS中怎么定义模块。
1 | // name和deps都是非必选的参数,而callback可以是一个对象,或者是具有返回值的函数 |
简单模块
如果一个模块只包含一些键值对,没有任何依赖,则在define()中定义这些键值对就好了
1 | // 定义模块时,推荐不显示传入name参数,这样方便优化工具去生成。 |
函数式模块
跟上篇文章说到的IIFE是一样的道理,加入我们需要对模块做一些初始化的工作,那么就不能使用简单模块的定义方式了。函数式模块的定义方式如下:
1 | define(function() { |
存在依赖的模块
假设你要写一个依赖jquery的模块,那么你需要在define方法中声明依赖。
1 | define(['jquery'], function($) { |
在官网上还发现一种类似sea.js的依赖写法。
1 | define(function(require, exports, module) { |
我的猜想:这种写法的代码在运行时,当前模块不知道所依赖的外部模块有哪些,需要遍历所有的require关键字,找出后面的依赖。这显然是一种更牺牲性能的方法。虽然可以用var $ = require('jquery')
这种“同步”的形式写代码,但终究不是一个最优的选择。
使用模块
在使用模块之前,我们可以通过require.config先配置每个js的路径,方便后续代码的书写。
1 | // main.js的顶部,我定义了四个模块的path |
RequireJS调用模块的方式如下
1 | // callback参数列表的顺序与deps中模块的顺序一致 |
1 | require(['simple', 'jquery', 'funcModule', 'depModule'], function(simple, $, funcModule, depModule) { |
到这里我们已经掌握了RequireJS的最基本的用法了。
配置项
除了paths外,RequireJS还支持很多的配置项,便于我们快速开发。完整配置可以参考RequireJS 中文网
比较常用的有baseUrl,指定了js文件的查找基路径;还有shim,用来作为垫片支持那些不符合AMD规范的js。
baseUrl
经过本人测试,baseUrl的路径参考了引用require.js的入口html文件。我们看一下两种不同的文件路径配置就明白了。
首先看第一种
接着我们看一下第二种,我把requirejs.html移动到了一个html文件夹内。
这两种不同的文件路径下,baseUrl都必须参考requirejs.html的路径,否则就会发生引用404报错了。
shim
有些早期的js库并不支持AMD写法,所以需要在requirejs中配置shim才可以使用它们,shim写法如下:
1 | require.config({ |
扫一扫下方小程序码或搜索Tusi博客
,即刻阅读最新文章!