requirejs初学

a.为什么要使用requireJS

很久之前,我们所有的JS文件写到一个js文件里面去进行加载,但是当业务越来越复杂的时候,需要分成多个JS文件进行加载,比如在页面中head内分别引入a.js,b.js,c.js等,如下所示:

1
2
3
<script src="js/app/a.js"></script>
<script src="js/app/b.js"></script>
<script src="js/app/c.js"></script>

这段代码依次加载多个js文件。这样的写法有很大的缺点。

  1. 页面在加载的时候,是从页面自上往下加载及渲染的,当页面上有多个分散的js文件时候,页面会先加载及解析头部的JS文件(同步加载),页面被堵塞了,其次分散的js请求数多了,网页失去响应的时间就会变长。
  2. 由于JS文件存在依赖关系,比如上面的b.js要依赖于a.js,所以务必保证a.js优先引入到页面上来且先加载,要严格保证加载顺序,依赖性最大的文件一定要放到最后加载。但是当依赖关系很复杂的时候,代码的编写和维护就会变得困难了。

b.使用requireJS的优点有哪些?

(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护;
(3)遵循AMD(异步模块定义)规范。

c.引用-reference

去requirejs官网下载http://www.requirejs.cn/docs/download.html,在页面头部head标签内引入requireJS,如下:

<script src="js/require.js"></script>,但是加载这个文件也会造成网页失去响应,我们可以加上 defer 和 async这个属性。如下:<script src="js/require.js" defer async="true" ></script>

data-main入口点

接下来,看看requireJS启动加载脚本的初始化方式,requireJS支持属性 data-main 这个属性来加载初始化的JS文件, 如下:

1
<script src="js/require.js" defer async="true" data-main="js/app.js"></script>

上面的意思是:先异步加载requireJS文件,完成后继续异步加载app.js文件

上面的app.js后的.js可以去掉,因为requireJS源码已经默认都是以后缀JS文件结尾的。

如何定义模块文件-define

RequireJS编写模块不同于其他脚本文件,它良好的使用define来定义一个作用域避免全局空间污染,它可以显示出其依赖关系,并以函数(定义此模块的那个函数)参数的形式将这些依赖进行注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-demo
   index.html
   -js
        require.js
        app.js
        -app
            a.js
            b.js
            c.js
            d1.js
            ....
            d6.js
        -lib
            jquery.js
            backbone.js
            underscore.js
1
2
3
4
5
6
7
8
9
10
11
12
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>require</title>
	<script data-main="js/app.js" src="js/require.js"></script>
</head>
<body>
    <div id="demo"></div>
</body>
</html>

在app.js初始化代码如下:

require(['app/d1'],function(d1){
	console.log(d1);
})

a.简单的值对,直接一个对象

//d1.js
define({
	color: "black",
	size: "24px"
});

b.函数式定义

//d2.js
define(function(){
	return {
		color: "red",
		size: "30px"
	}
});

c.存在依赖的函数式定义

例如d3.js 依赖a.js

//d3.js
define(['./a'],function(a){
	return {
		color: "blue",
		add: a.add(1,2)
	}
})
//a.js
define(function(){
	return{
		add: function(a,b){
			return a+b
		}
	}
})

d.将模块定义为一个函数

//d4.js
define(['./a'],function(a){
	return function(){
		return a.add(1,2)
	}
})

e.定义一个命名模块

//d5.js
 define("myname",['./a'],function(a)) {
            //todo
       }
    );

以上命名函数写法,移植需要重命名,不推荐使用

f.简单包装CommonJS来定义模块

//d6.js
define(function(require,exports,module){

	var a = require('./a');

	exports.show =  function() {
		return a.add(1,2);
	}
});

requireJS配置项

baseUrl :

所有模块的查找根路径。

//app.js
requirejs.config({
    baseUrl: 'js/app'
});

requirejs(['a','b','c'],function(a,b,c){

});

paths:

是映射那些不直接放在baseUrl指定的目录下的文件。设置paths的起始位置是相对于baseUrl的,除非该path设置是以”/”开头或含有URL协议(‘http://’或者’https://’).

app.js
requirejs.config({
	baseUrl: 'js/lib',
	paths: {
		myapp: '../app'
	}
});

require(['jquery','myapp/b'],function($,b){
	$("#demo").append("hello world");
});

shim:

为那些没有使用define()来声明依赖关系、设置模块的”浏览器全局变量注入”型脚本做依赖和导出配置。

require.config({
    shim: {

      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
  });

Map参数:

Map参数是用来解决同一个模块不同版本的问题
building…

更多-more