引入
下载 requireJs
,然后在 head
中
1 | <script src="js/require.js" data-main="js/main" defer async="true"></script> |
async
属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持 defer
,所以把 defer
也写上。
data-main
属性的作用是,指定网页程序的主模块。在上例中,就是js目录下面的 main.js
,这个文件会第一个被 require.js
加载。由于require.js
默认的文件后缀名是js,所以可以把 main.js
简写成 main
。
基本API
require
会定义三个变量:define, require, requirejs,其中 require
=== requirejs
,一般使用 require
更简短
- define 从名字就可以看出这个api是用来定义一个模块
- require 加载依赖模块,并执行加载完后的回调函数
比如我们想写一个 a.js 的模块,实现一个功能:
1 | define(function(){ |
这里通过 define
函数定义了一个模块,这是 requirejs
的标准写法。如果想在页面中使用该 js ,可以直接在 html
文件中调用:
1 | require(["js/a"]); |
如果我们的网页目录如下:
并且 index.html
内容如下,通过主动 require
的方式调用 a.js:
1 | <!DOCTYPE html> |
这时候网页就会弹出一个alert 对话框:
如果将 index.html
写成如下:
1 | <!DOCTYPE html> |
那么会在 ‘It works’ 后,再弹出一个对话框:
加载文件和全局配置
也许你会说,这样调用的方式,如果我有 a,b,c,d… 等 js 代码,不还是得一个个写到 head
里的 <script>
标签内调用么。不急,下面才是重点。
首先我们在 js 目录下新建一个 main.js
:
然后在 main.js
中写如下代码:
1 | require.config({ |
然后在 index.html
中这样写:
1 | <!DOCTYPE html> |
这里用到了 require.config
。require.config
是用来配置模块加载位置的。即给我们的 js 模块,取一个 别名,之后进行 require
的时候,就不用以输入路径的方式来调用,直接写这个 别名 就行。
可以看到上面代码写 require
的时候,直接是使用 require(['a']
而不是之前的 require(["js/a"]
。
这样如果我们有很多的代码,就可以在 main.js
中,先配置各个模块的路径,并起别名,然后挨个 require
调用就是了。就不用对 head
标签进行修改。
同时如果我们在 index.html
中这样写:
1 | <script type="text/javascript" src="js/lib/require.js" data-main="js/main" defer async="true"></script> |
这里 data-main
属性的作用是,指定网页程序的主模块。在上例中,就是js目录下面的 main.js
,这个文件会自动被 require.js
加载。这样我们就只用写一个 <script>
标签,就实现了对所有的 js 模块的调用。
data-main
还有一个重要的功能:
当 script
标签指定 data-main
属性时,require
会默认的将 data-main
指定的 js 为根路径。即之后如果写 require
来调用 js 模块,不需要再添加 ‘js’ 目录前缀。
async
属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持 defer
,所以把 defer
也写上。
下面是使用 data-main
属性时候的 html 和 js 文件写法:
1 | <!DOCTYPE html> |
1 | require.config({ |
加载不符合AMD规范模块
标准的写法是需要使用一个:
1 | define(function(){ |
将你的代码写在这个 define
内部。但是我们如果想要使用一个不是这种标准的 js 模块怎么破?
这里就要使用到 shim
。我们看下面的完整配置 main.js
:
1 | requirejs.config({ |
这里假设我使用了 jquery
和 bootstrap
模块,还有一个自己写的业务脚本 my.js
。 my.js
因为要依赖于 jquery
和 bootstrap
所以在依赖关系中写了上面的配置。
关键在于 export
关键字的声明。这样我们就可以加载一个没有使用 AMD
规范编程的 js 模块了。并且模块的所有变量,和函数,都不是在全局域的,只在 回调函数中有效。从而避免了全局变量的污染问题。