使用 RequireJS 按需动态加载JS

PS:基于 AMD(Asynchronous Module Definition)的 JavaScript 设计已经在目前较为流行的前端框架中大行其道,jQuery、Dojo、MooTools、EmbedJS 等纷纷在其最新版本中加入了对 AMD 的支持。本文介绍的是另一款较为精简的 RequireJS 框架,既想使用 AMD 的特性又不想引入一个庞大的库的开发人员,不妨试试 RequireJS。RequireJS 可以帮助用户异步按需的加载 JavaScript 代码,并解决 JavaScript 模块间的依赖关系,提升了前端代码的整体质量和性能

  1. AMD 介绍

    前端开发在近一两年发展的非常快,JavaScript作为主流的开发语言得到了前所未有的热捧。大量的前端框架出现了,这些框架都在尝试着解决一 些前端开发中的共性问题,但是实现又不尽相同。在这个背景下,CommonJS社区诞生了,为了让前端框架发展的更加成熟,CommonJS鼓励开发人员 一起在社区里为一些完成特定功能的框架制定规范。 AMD(Asynchronous Module Definition) 就是其中的一个规范。

  2. 传统JavaScript代码的问题

    让我们来看看一般情况下JavaScript代码是如何开发的:通过<script>标签来载入JavaScript文件,用全局变量 来区分不同的功能代码,全局变量之间的依赖关系需要显式的通过指定其加载顺序来解决,发布应用时要通过工具来压缩所有的JavaScript代码到一个文 件。当Web项目变得非常庞大,前端模块非常多的时候,手动管理这些全局变量间的依赖关系就变得很困难,这种做法显得非常的低效。

  3. AMD (Asynchronous Module Definition) 的引入

    从名称上看便知它是适合script tag的。也可以说AMD是专门为浏览器中JavaScript环境设计的规范。它吸取了CommonJS的一些优点,但又不照搬它的格式。开始AMD作为CommonJS的transport format存在,因无法与CommonJS开发者达成一致而独立出来。它有自己的wiki讨论组

    AMD提出了一种基于模块的异步加载JavaScript代码的机制,它推荐开发人员将JavaScript代码封装进一个个模块,对全局对象的依 赖变成了对其他模块的依赖,无须再声明一大堆的全局变量。通过延迟和按需加载来解决各个模块的依赖关系。模块化的JavaScript代码好处很明显,各 个功能组件的松耦合性可以极大的提升代码的复用性、可维护性。这种非阻塞式的并发式快速加载JavaScript代码,使Web页面上其他不依赖 JavaScript代码的UI元素,如图片、CSS以及其他DOM节点得以先加载完毕,Web页面加载速度更快,用户也得到更好的体验。

    1. CommonJS的AMD规范中只定义了一个全局的方法,如清单1所示

                      define(id?, dependencies?, factory);
                      

      该方法用来定义一个 JavaScript 模块,开发人员可以用这个方法来将部分功能模块封装在这个 define 方法体内

    2. dependencies 是一个字符串 Array,表示该模块依赖的其他所有模块标识,模块依赖必须在真正执行具体的 factory 方法前解决,这些依赖对象加载执行以后的返回值,可以以默认的顺序作为 factory 方法的参数。dependencies 也是可选参数,当用户不提供该参数时,实现 AMD 的框架应提供默认值为 [“require”,”exports”,“module”]。
    3. factory 是一个用于执行改模块的方法,它可以使用前面 dependencies 里声明的其他依赖模块的返回值作为参数,若该方法有返回值,当该模块被其他模块依赖时,返回值就是该模块的输出。
    4. CommonJS 在规范中并没有详细规定其他的方法,一些主要的 AMD 框架如 RequireJS、curl、bdload 等都实现了 define 方法,同时各个框架都有自己的补充使得其 API 更实用。

  4. AMD设计出一个简洁的写模块API:

            define(id?, dependencies?, factory);
            

    其中:

    • id: 模块标识,可以省略。
    • dependencies: 所依赖的模块,可以省略。
    • factory: 模块的实现,或者一个JavaScript对象。

    以下是使用AMD模式开发的简单三层结构(基础库/UI层/应用层):

    1. 定义无依赖的模块

      (base.js)

                      define(function() {
                          return {
                              mix: function(source, target) {
                              }
                          };
                      });
                      
    2. 定义有依赖的模块

      (ui.js,page.js)
      ui.js

                      define(['base'], function(base) {
                          return {
                              show: function() {
                                  // todo with module base
                              }
                          }
                      });
                      

      page.js

                      define(['data', 'ui'], function(data, ui) {
                          // init here
                      });
                      
    3. 定义数据对象模块 (data.js)

                      define({
                         users: [],
                        members: []
                      });
                      
    4. 具名模块

                      define('index', ['data','base'], function(data, base) {
                          // todo
                      });
                      

      具名模块多数时候是不推荐的,一般由打包工具合并多个模块到一个js文件中时使用。

    5. 包装模块

      前面提到dependencies元素的顺序和factory一一对应,其实不太严谨。AMD开始为摆脱CommonJS的束缚,开创性的提出了自己的模块风格。但后来又做了妥协,兼容了 CommonJS Modules/Wrappings 。即又可以这样写

                      define(function(require, exports, module) {
                          var base = require('base');
                          exports.show = function() {
                              // todo with module base
                          }
                      });
                      

      不考虑多了一层函数外,格式和Node.js是一样的。使用require获取依赖模块,使用exports导出API

    除了define外,AMD还保留一个关键字require。
    require 作为规范保留的全局标识符,可以实现为module loader。也可以不实现。

    目前,实现AMD的库有RequireJS 、curl 、Dojo 、bdLoadJSLocalnet 、Nodules 等。

    也有很多库支持AMD规范,即将自己作为一个模块存在,如MooTools 、jQuery 、qwery 、bonzo  甚至还有 firebug

  5. 简单示例

            
            
                
    
                    
                    
                    
                 
                 
                ...
                 
            
            

    main.js

            require.config({
                paths: {
                    jquery: 'jquery-1.7.2'
                }
            });
    
            require(['jquery'], function($) {
                alert($().jquery);
            });
            

    main.js中就两个函数调用require.config和require。

    • require.config用来配置一些参数,它将影响到requirejs库的一些行为。require.config的参数是一个JS对象,常用的
      配置
      有baseUrl,paths等。
    • 这里配置了paths参数,使用模块名“jquery”,其实际文件路径jquery-1.7.2.js(后缀.js可以省略)。

    这里require函数的第一个参数是数组,数组中存放的是模块名(字符串类型),数组中的模块与回调函数的参数一一对应。这里的例子则只有一个模块“jquery”。


    • 我们知道jQuery从1.7后开始支持AMD规范,即如果jQuery作为一个AMD模块运行时,它的模块名是“jquery”。注意“jquery”是固定的
      ,不能写“jQuery”或其它。
    • 如果文件名“jquery-1.7.2.js”改为“jquery.js”就不必配置paths参数了。
    • require.config中config可以省略

    jQuery中的支持AMD代码如下

            if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
              define( "jquery", [], function () { return jQuery; } );
            }
            

    访问index.html,网络请求如下

    我们看到除了require.js外main.js和jquery-1.7.2.js也请求下来了。而它们正是通过requirejs请求的

  6. 实例包下载

参考:
1.AMD和RequireJS初识—-优化Web应用前端(按需动态加载JS)
2.使用 RequireJS 优化 Web 应用前端

200-120
210-260
200-310
SY0-401
810-403
300-320
400-101
70-533
N10-006
MB2-707
210-060
400-201
350-018
ADM-201
CISSP
1Z0-060
400-051
300-075
MB2-704
100-101
9L0-012
642-999
300-115
MB5-705
70-461
1V0-601
300-206
352-001
70-486
300-135
NS0-157
PR000041
300-101
70-346
CCA-500
70-480
300-208
70-462
EX200
1Z0-803
EX300
ICBB
1Z0-808
AWS-SYSOPS
1Z0-434
300-070
CAS-002
220-801
SSCP
PMP
642-997
70-410
101-400
ITILFND
AX0-100
2V0-621
102-400
101
1Z0-067
220-802
70-463
C_TAW12_731
70-494
CISM
700-501
NSE4
NSE7
70-483
70-488
相关文章
  1. fis3-smarty 安装使用详解
  2. 在CentOS6.5上安装Node.js
本站版权
1、本站所有主题由该文章作者发表,该文章作者与尘埃享有文章相关版权
2、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和尘埃的同意
3、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
5、原文链接:
二维码
Posted in JavaScript, 编程语言
Comments are closed.