require.js
RequireJS 是一个 JavaScript 文件和模块载入工具,针对浏览器使用场景优化,块作用域来申明function防止污染全局变量,声明不同js文件之间的依赖,按需、并行、延时载入js库,可应用到其他 JavaScript 环境中如 Rhino 和 Node.js
官网 //requirejs.org/
RequireJS是模块化加载js文件的框架
基于AMD规范实现 方便 js文件的异步加载
引入require.js的正确姿势
<script src="https://cdn.bootcss.com/require.js/2.3.5/require.min.js"></script>
<script>window.require||document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.min.js"><\/script>')</script>
RequireJS采用的异步加载 前一个js文件没加载完毕,不会影响后一个js文件的加载
RequireJS加载的js文件 在独立的命名空间 js文件出现相同的变量不会产生冲突
RequireJS模块化的js让代码重用能力得到提高 团队协作开发更便利等
index.html文件
<!DOCTYPE html>
<head><meta charset="UTF-8"><title>Test</title></head>
<body>
<h1>Hello World!</h1>
<script src="https://cdn.bootcss.com/require.js/2.3.5/require.min.js"></script>
<script>window.require||document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.min.js"><\/script>')</script>
<script type="text/javascript">
require(['app/a'], function(obj) {document.write('name: ' + obj.name + ', age: ' + obj.age);});
</script></body></html>
1、js目录存放的是所有的js文件
2、js/app目录存放的 自定义的模块js文件
3、js/lib目录存放的 js框架文件如jquery、react等
4、require.min.js是RequireJS框架的主文件
5、main.js是当require框架文件加载完毕后,首先执行的 文件 类似于C语言中的main函数
6、index.html是使用RequireJS模块化加载js文件的网页
配置RequireJS的参数
main.js的代码所示
require.config({
baseUrl: 'js/lib',
paths: {
app: '../app'
}
})
使用require.config()方法为requirejs框架配置一些属性,如上面代码中配置的baseUrl和paths。其中:
1、baseUrl属性指定了一个默认的路径,配置了该属性后,requirejs框架加载的所有js文件,都是以这个路径为基准的
2、paths属性指定了一系列的键值对,可以很方便地为一些较长的文件路径设置一个短的别名,例如下面的代码:
paths : {
"jquery" : ["http://libs.baidu.com/jquery/2.0.3/jquery"]
}
即用jquery代表了http://libs.baidu.com/jquery/2.0.3/jquery路径。
使用RequireJS加载模块
需要加载jquery时 require(['jquery'], function($) { });
需要加载自定义的a.js模块时 main.js中 paths里定义了一个app 值为‘../app’
表示使用app代替路径’../app’,注意这里的‘../app’路径是相对于baseUrl中指定的路径的
可以用如下代码来加载a.js模块:
require(['app/a'], function() {
//这里的'app/a'就相当于加载了'js/app/a.js'文件,
这里的'app/a'是不带文件后缀.js的,而且也不允许带后缀,否则无法正确加载js文件
});
require(['app/a'], function() {});
表示加载’app/a’这个模块,require()方法的第一个参数必须是一个数组
哪怕仅仅只加载一个模块;第二个参数是一个回调函数
当模块成功加载后得到执行
如何编写自定义的模块
编写自定义的模块时,也需要遵循AMD规范
1、自定义一个对象:
a.js文件
define({name: 'zhangsan',age: 18});
定义可被RequireJS加载的模块,需要使用define()方法,定义对象模块,直接在define()方法中传入这个对象即可,在加载并使用这个对象时
require(['app/a'], function(obj) { document.write('name: ' + obj.name + ', age: ' + obj.age); });
回调函数中的obj参数就代表了在define()中传入的对象,可以直接使用obj.name和obj.age来访问这个对象的属性
2、自定义一个没有任何依赖的方法:
a.js文件代码
define(function() {
var name = 'zhangsan', age = 20, sayHello = function(name, age) { document.write('hello, my name is: ' + name + ', my age is: ' + age); };
sayHello(name, age);
})
要定义一个函数模块,只需在define()的参数中传入一个函数function即可
在使用这个模块时
require(['app/a'], function() {});
加载完毕a模块后,执行a.js中定义的函数,打开浏览器后结果
3、自定义一个有依赖的方法:
a.js文件
define(['jquery'], function($) { $('h1').css('color', 'red'); });
在main.js中的paths中,加入如下配置:
"jquery": ["http://libs.baidu.com/jquery/2.0.3/jquery"]
然后在index.html文件中加载a模块
require(['app/a'], function() {});
a.js文件中的define()方法带有两个参数,第一个参数为一个数组,表示这个模块依赖的其他模块,
由于在main.js配置文件中配置了jquery,所以a模块中依赖的jquery会被加载,加载完毕后,
在define()方法的第二个参数,也就是回调函数中,使用加载好的jquery,用$获取h1标签,然后将h1标签变成红色。
4、将一个方法作为模块:
a.js文件
define(function() { return function(a, b) { return a + b; } });
define()方法中传入了一个function,该function的返回值为一个function,
传入两个参数a,b,然后返回a + b的值,在index.html文件中加载a模块
require(['app/a'], function(add) { document.write('3 + 2 = ' + add(3, 2));});
5、简单包装CommonJS来定义模块
a.js文件
define(function(require, exports, modules) {
var a = require('a'),b = require('b'); //Return the module value
return function () {};
});
6、定义一个命名模块:
a.js文件
define("app/test", [], function() {});
define()中有3个参数,分别代表模块名、依赖的模块、回调函数,该方式不推荐使用,因为属于硬编码的模块,不利于模块的扩展和复用
依赖不使用requirejs方式的库
如果没用define(...) 定义模块 hello.js 通方式定义了一个函数
function hello() {
alert("hello, world~");
}
用shim 将某个依赖中的某个全局变量暴露给requirejs当作这个模块本身的引用
requirejs.config({
baseUrl: '/public/js',
paths: {
hello: 'hello'
},
shim: {
hello: { exports: 'hello' }
}
});
requirejs(['hello'], function(hello) {
hello();
});
exports: 'hello' 中的 hello ,是hello.js 中定义的 hello 函数
使用function hello() {} 的方式定义一个函数的时候,它就是全局可用的
如果选择了把它 export 给requirejs,那代码依赖于 hello 模块的时候,就可以拿到这个hello 函数的引用了
exports 可以把某个非requirejs方式的代码中的某一个全局变量暴露出去,当作该模块以引用
暴露多个变量:init
如果我要同时暴露多个全局变量呢?比如, hello.js 的定义其实是这样的:
function hello() {
alert("hello, world~");
}
function hello2() {
alert("hello, world, again~");
}
它定义了两个函数,而我两个都想要。这时就不能再用exports了,必须换成 init 函数:
requirejs.config({
baseUrl: '/public/js',
paths: {
hello: 'hello'
},
shim: {
hello: {
init: function() {
return {
hello: hello,
hello2: hello2
}
}
}
}
});
requirejs(['hello'], function(hello) {
hello.hello1();
hello.hello2();
});
当 exports 与 init 同时存在的时候, exports 将被忽略。
尊贵的董事大人
英文标题不为空时 视为本栏投稿
需要关键字 描述 英文标题