概述
node作为一个服务端语言,在加载模块时,模块都是在本地磁盘,因此可以以可观的速度加载进来,因此,在node里的模块加载都是同步的,阻塞时间都不会太长。
如果我们要在浏览器端的js来实现模块设计模式呢,这就意味着我们需要远程从服务器加载所以定义的模块,浏览器js引擎的阻塞时间可想而知。
如果不使用模块设计模式的话,那各个js文件互相依赖,而且共享一个顶层作用域window,很容易出现变量重定义的错误。比如下面这种形式。
各个文件互相依赖,耦合性很高。
但是如果我们要用模块设计模式的话,那么各个模块必须用异步加载,如果不用异步加载,浏览器很可能处于很长时间的阻塞状态,造成很糟糕的用户体验。因此AMD孕育而生。
AMD 模块定义
define 接受3个参数,id是模块化标识可以省略,第二个参数可以省略,在没有依赖于其他模块的情况下,可以将第一个参数省略,因此,我们可以这样定义。
与commonJS 也有一些相似之处,commonJS 暴露给外部的接口为module.exports 所指向的对象,而AMD 暴露给外部的接口为return 的对象,
这里我暴露了一个json对象,key 为外部调用的名称,value 为名称指向的对象。
如果我们定义的模块依赖于其他的模块,比如我们依赖于一个hello的模块。
这时,我们的模块需要这样定义:
定义数据对象模块 (data.js)
RequireJS
RequireJS
现在有很多AMD规范的库 RequireJS就很不错········呵呵呵别的懒得看了而已
看个极简的例子:
首先要到requirejs的网站去下载require.js
requireJS 定义了三个变量:define,require,requirejs,其中requirejs===require,一般用require 因为懒是天性。
- define 定义一个模块。
- require 加载依赖模块,并执行加载完成后的回调函数。
通过define函数定义了一个模块,然后再页面中使用:
来加载该模块(注意require中的依赖是一个数组,即使只有一个依赖,你也必须使用数组来定义),require API的第二个参数是callback,一个function,是用来处理加载完毕后的逻辑,如:
RequireJS全局配置
我们可以通过require.config来配置复杂的加载文件
paths还有一个重要的功能,就是可以配置多个路径,如果远程cdn库没有加载成功,可以加载本地的库.
我们不可能每个文件都写require.config,requirejs提供了一种叫”主数据”的功能,我们首先创建一个main.js
加载requirejs脚本的script标签加入了data-main属性,这个属性指定的js将在加载完reuqire.js后处理,我们把require.config的配置加入到data-main后,就可以使每一个页面都使用这个配置,然后页面中就可以直接使用require来加载所有的短模块名
data-main还有一个重要的功能,当script标签指定data-main属性时,require会默认的将data-main指定的js为根路径
RequireJS shim
为那些没有使用define()来声明依赖关系、设置模块的”浏览器全局变量注入”型脚本做依赖和导出配置。