requireJS学习笔记一

requireJS简介
requireJS是一个非常小巧的javascript模块载入框架,很好的实现了AMD规范。
requireJS解决了以下问题:
  1、异步加载js,防止js加载阻塞页面渲染;
  2、管理js模块之间的相互依赖关系,便于代码维护。
data-main入口
requireJS在加载过程中会检测script标签的data-main属性:
1 <script data-main="js/app" src="js/require.js"></script>

data-main指定的app.js会异步载入页面。

由于app.js是异步载入的,那么页面后面加载的js就不一定比app.js后载入,因此页面后面加载的js不要依赖于app.js。

1 <script data-main="js/app" src="js/require.js"></script> <!-- app.js是异步载入的 -->
2 <script src="js/app/sub.js"></script> <!-- sub.js可能比app.js先载入 -->

 

requireJS配置
通过对requireJS的配置可以给模块添加别名、添加版本标识、设置模块依赖、包装非模块。
配置文件的位置:
  1、配置文件在requireJS的后面,将配置参数放在require.config()里面
 1   <script src="js/require.js"></script>
 2   <script>
 3     require.config({
 4       baseUrl: js,
 5       paths: {
 6         app: ./app/
 7       }
 8     });
 9     require([app/module, my/module, a.js, b.js], function(some, my){
10       // do any thing
11     });
12   </script>

  2、配置文件在requireJS的前面,由于requireJS后加载使用require.config()会报错,只有声明全局变量require来注入配置参数。

1   <script>
2     var require = {
3       baseUrl: js,
4       paths: {
5         lib: lib
6       }
7     };
8   </script>
9   <script src="js/require.js"></script>

  NOTE:

    在工作中requireJS的配置文件最好单独放在一个文件,避免和业务耦合;

    另外使用第二种方式时,用var require = {}而不要使用window.require = {}(IE中运行有问题)。

配置参数详解:

  1、baseUrl:模块查找的根目录。

    当require以/开头、带有协议(http:...)和.js结尾的依赖时,不会参考baseUrl;

    未显示设置baseUrl时,默认是加载requireJS的html文件所在的目录;

    如果使用了data-main属性,baseUrl就是该属性所指的js文件所在的目录。

  2、paths:映射那些不直接放在baseUrl目录下的模块名。

    paths的参考路径是baseUrl,除非设置的模块以/开头或带有协议(http:...);

    应用模块名的path不应该有.js后缀,因为path可能映射到一个目录,并且requireJS的路径解析会在映射模块名到path时自动添加.js后缀。

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

    由于requireJS加载的模块必须是按照AMD规范编写的,那么shim可以用来定义那些没有按照AMD规范编写的外部库,比如backbone、underscore。

 1   <script src="js/require.js"></script>
 2   <script>
 3     require.config({
 4       baseUrl: js,
 5       paths: {
 6         jQuery: lib/jQuery,
 7         backbone: lib/backbone,
 8         underscore: lib/underscore
 9       },
10       shim: {
11         backbone: {
12           deps: [underscore, jQuery], // 定义依赖关系
13           exports: Backbone
14         },
15         underscore: {
16           exports: _
17         }
18       }
19     });
20     require([backbone], function(){
21     });
22   </script>

  4、map:同一个模块不同版本的加载。

    对于某些大型项目:如果有两类模块需要使用不同版本的foo,可以这样做。

 1   <script src="js/require.js"></script>
 2   <script>
 3     require.config({
 4       baseUrl: js,
 5       paths: {
 6         app: app,
 7       },
 8       map: {
 9         app/sub: {
10           foo: foo1.0
11         },
12         app/sup: {
13           foo: foo1.2
14         }
15       }
16     });
17     require([app/sub], function(){});
18     //
19   </script>

    当app/sub调用require(‘foo‘),它将引用foo1.0.js文件,而当app/sup调用require(‘foo‘)时,它将引用foo1.2.js文件。

    map仅适用那些调用了define()并将其注册为匿名模块的真正AMD模块,并且在map配置中仅仅使用绝对模块ID

    map中还支持*号,表示对所有的模块加载,使用本配置

  5、waitSeconds:超时设定。

    默认7秒。如果设置为0禁用等待超时。

  6、urlArgs:requireJS获取资源时附加在URL后的额外参数。

 1   <script src="js/require.js"></script>
 2   <script>
 3     require.config({
 4       baseUrl: js,
 5       paths: {
 6         app: app,
 7       },
 8       urlArgs: version=1.0
 9     });
10     require([app/sub], function(){}); // 页面加入的js文件js/app/sub.js?version=1.0
11   </script>

  还有些其他配置项,等用得上的时候补充。。。。

模块定义
模块不同于传统的脚本文件,模块定义了一个作用域来避免全局名称的污染。
模块可以显示的列出其依赖关系,并以函数参数的形式将这些依赖进行注入,无需引用全局变量。
由于无需创建全局变量,所以可以做到同一个页面加载同一模块的不同版本。
模块的定义:
  1、简单的键值对
1 define({
2   name: ‘hum‘,
3   age: 26,
4   sex: ‘female‘
5 });

  NOTE:用途不大

  2、无依赖函数式定义

1 define(function(){
2   // do something
3   
4   return {
5     color: ‘black‘,
6     size: ‘big‘
7   }
8 });

  NOTE:适合无依赖模块的编写。没有return语句返回undefined。

  3、有依赖函数式定义

1 define([‘jQuery‘], function($){
2   return {
3     color: ‘red‘,
4     size: ‘big‘,
5     add: function(){
6       console.log(‘add‘);
7     }
8   }
9 });

  NOTE:定义模块最常见的用法。

  4、将模块定义为一个函数

1 define([‘jQuery‘], function($){
2   return function(title){
3     return title || ‘hum‘;
4   }
5 });

  NOTE:该模块返回的是一个闭包

  5、简单包装CommonJS来定义模块

    这种方式效率底下,不考虑使用。

  6、定义一个命名模块

1 define(‘app/sub‘, [‘jQuery‘], function($){
2   // do something
3 });

  NOTE:将模块名作为define()的首个参数。这样显示定义模块名不具备移植性。一般让其他工具去添加以便让多个模块合并到一个文件。

  7、JSONP服务依赖

1 require([‘http://www.example.com/data.json?callback=define‘], function(data){
2   // callback的方法名是define
3   console.log(data);
4 });

  NOTE:为了在requireJS中使用JSONP返回的值,必须将callback参数的值指定为define。返回值必须是JSON对象。

模块的加载
模块加载调用:
1 require([‘模块名,...‘], function(模块对应参数){
2   // do something
3 });

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。