参考:
官方文档API
Javascript模块化编程(三):require.js的用法
JS模块化工具requirejs教程(一):初识requirej
RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一
1 基本API
require会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短
- define 从名字就可以看出这个api是用来定义一个模块
- require 加载依赖模块,并执行加载完后的回调函数
1.1 define
定义一个模块是通过 define (name, deps, callback)完成的,第一个参数是定义模块名,第二个参数是传入定义模块所需要的依赖,第三个函数则是定义模块的主函数,主函数和require的回调函数一样,同样是在依赖加载完以后再调用执行。1.1.1 当没有任何依赖的时候可以按照下面的来写
define(function(){
return{
decs : 'this js will be request only if it is needed',
};
})
1.1.2 当有相关依赖时可以按下面的来写
define(['jquery'],function($){
return function (){
alert('asas');
};
})
1.1.3 为什么我始终都没有使用name来定义自己的模块名
如果你细心,你可能会发现,刚刚define函数,有一个参数name是用来定义模块名的(也就是第一个传参),为什么上面两个例子都没有用到。其实我确实可以添加模块名,如下:
但是,这样做感觉不很有必要,因为如果哪一天我将这个文件转移到其他目录下,那我就得在这这里再修改一次模块名。官方其实也不推荐,用官方的说法是:让优化工具去自动生成这些模块名吧define(['jquery'],function($){
return function (){
alert('asas');
};
})
1.2 require
1.2.1 加载依赖模块,并执行加载完后的回调函
``` // main.jsrequire(["js/a"],function(){
alert("load finished");
})
require([‘moduleA’, ‘moduleB’, ‘moduleC’], function (moduleA, moduleB, moduleC){
// some code here
});
require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是['moduleA', 'moduleB', 'moduleC'],即主模块依赖这三个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。 require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块 都加载成功后,才会运行,解决了依赖性的问题。<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/102566/1596610357879-f4b5f0e6-c5ed-49a8-b3e2-ff4aa53e7784.png#align=left&display=inline&height=262&margin=%5Bobject%20Object%5D&name=image.png&originHeight=524&originWidth=1758&size=92232&status=done&style=none&width=879)
<a name="3M9U2"></a>
#### <br />1.2.2 require.config
上面的例子,默认情况下,require.js假定这三个模块与main.js在同一个目录,文件名分别为jquery.js,underscore.js和backbone.js,然后自动加载。
实际情况,可能不是在同一目录,或者从网络获取
使用require.config()方法,我们可以对模块的加载行为进行自定义。require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。
require.config({ paths: { “jquery”: “jquery.min”, “underscore”: “underscore.min”, “backbone”: “backbone.min” } });
```
require.config({
paths: {
"jquery": "lib/jquery.min",
"underscore": "lib/underscore.min",
"backbone": "lib/backbone.min"
}
});
require.config({
baseUrl: "js/lib",
paths: {
"jquery": "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"
}
});
require.config({
paths: {
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
}
});
2 实际案列
2.1 编写模块代码
index.js
/**
* 1、模块路径配置
* 2、配置不兼容模块
**/
requirejs.config({
baseUrl: '//js.xxx.com/multi/src/',
urlArgs:"342342",
paths: {
lib: 'common/base',
tools: 'common/tools',
ui: 'common/ui',
tpl: 'common/tpl',
header: 'common/header',
lang: 'common/lang'
},
shim: {
'lib/backbone': {
deps: ['lib/underscore', 'lib/jquery'],
exports: 'Backbone'
},
'lib/underscore': {
exports: '_'
},
'lib/jquery': {
exports: '$'
},
'tools/jquery.cookie': {
deps: ['lib/jquery'],
exports: '$cookie'
}
}
});
//调用入口文件
requirejs(['competitor/main']);
main.js
define(
'competitor/main',
[
'common/config',
'common/langLoader',
'common/feedback',
'common/googletranslate',
'tools/jquery.cookie',
'competitor/uploader' ],
function(
CONFIG,
langLoader,
feedback,
translate,
JCookie,
Uploader
){
console.log(1)
new Uploader()
});
2.2 页面引入
页面引入requirejs和使用requirejs开发的项目
2.3 加载模块代码
requriejs会判断依赖是否存在,不存在则会去请求,就是在头部动态加入script标签
可以发现,每个依赖的js模块文件,requirejs都会去获取
只有依赖都下载后才会执行模块内代码。
2.4 生产环境-合并代码
使用 RequireJS 可以将我们的 JavaScript 代码轻易的分割成苦干个模块(module),方便我们的开发与维护。但是在生产环境中,如果将所有的 JavaScript 文件分离,会导致很多次请求(requests),即使这个些文件都很小,也会浪费很多时间。
所以在生产环境中,我们可以通过合并这些脚本文件,以减少请求的次数达到节省加载时间的目的。
RequireJS 提供了一个打包压缩工具 r.js,它是一个能运行基于 AMD 的项目的命令行工具,可以用来实现对模块的合并压缩。
也可以配合其他构件工具,如gulp、grunt等等。
还有其他合并代码的方式,见过使用php写一个合并文件的方法,配合wamp或nginx,在本地搭建一套开发环境,达到合并代码的目的。