码迷,mamicode.com
首页 > Web开发 > 详细

requireJS使用

时间:2015-08-09 00:21:42      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

requireJS使用

requirejs使用


  1. 开篇引题
  2. 为什么使用require.js
  3. require.js加载
  4. 配置require:config方法
  5. define方法:定义模块
  6. require方法:调用模块
  7. require合并
  8. 实例列表
  9. 参考文档

开篇引题

随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂。网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑。

Javascript模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块
Javascript不是一种模块化编程语言,它不支持"类"(class),就不用谈论模块了。尽管通过匿名函数自执行(返回方法)或者面向对象等方式,使其看似模块化,但如何保证方法与调用之间的依赖关系是一个值得思考的问题,在这个基础上require.js诞生了

目的

通过此次对require.js的分享,能让大家把它应用到项目中,提高代码的复用性,使之呈现模块化编程,提高页面加载速度为以后实现前端组件库奠定基础。

方式方法

本次分享采取文字与事例相结合的方式,代码托管在github上,地址是https://github.com/lisongyu/requirejs-learnt,大家可以一起学习讨论

为什么使用require.js

使用RequireJS的目标是鼓励代码的模块化,它使用了不同于传统标签的脚本加载步骤。可以用它来加速、优化代码,但其主要目的还是为了代码的模块化。它鼓励在使用脚本时以module ID替代URL地址。

requirejs的优势

1实现js文件的异步加载,避免网页失去响应,提高性能;
2管理模块之间的依赖性,便于代码的编写和维护。
3.实现了代码的模块化,便于复用。

requirejs是什么?

RequireJS是一个工具库,主要用于客户端的模块管理。它可以让客户端的代码分成一个个模块,实现异步或动态加载,从而提高代码的性能和可维护性。它的模块管理遵守AMD规范(Asynchronous Module Definition)。

AMD 模块

AMD(异步模块定义,Asynchronous Module Definition)格式总体的目标是为现在的开发者提供一个可用的模块化 JavaScript 的解决方案。

RequireJS的基本思想是,通过define方法,将代码定义为模块(插件);通过require方法,实现代码的模块加载。


3.require.js加载

使用require.js的第一步,是先去官方网站下载最新版本。
下载后,假定把它放在JavaScript子目录下面,就可以加载了。

<script data-main="scripts/main" src="scripts/require.js"></script>

上面代码的data-main属性不可省略,用于指定主代码所在的脚本文件,在上例中为scripts子目录下的main.js文件。用户自定义的代码就放在这个main.js文件中。


4.配置require:config方法

为什么使用require
require方法本身也是一个对象,它带有一个config方法,用来配置require.js运行参数。config方法接受一个对象作为参数。一般配置项都在页面data-main所指的js中,本文所指main.js。

require.config({
    baseUrl: "javascript",
    //packages: [‘carousel‘],
    paths: {jquery: [‘//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js‘,‘lib/jquery.min‘],
        bootstrap: ‘lib/bootstrap‘
    }
});

config方法的参数对象有以下主要成员:
(1)baseUrl

baseUrl参数指定本地模块位置的基准目录,即本地模块的路径是相对于哪个目录的。该属性通常由require.js加载时的data-main属性指定。

(2)paths

paths参数指定各个模块的位置。这个位置可以是同一个服务器上的相对位置,也可以是外部网址。可以为每个模块定义多个位置,如果第一个位置加载失败,则加载第二个位置,上面的示例就表示如果CDN加载失败,则加载服务器上的备用脚本。需要注意的是,指定本地文件路径时,可以省略文件最后的js后缀名。

(3)shim
通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim,shim解释起来也比较难理解,shim直接翻译为"垫",其实也是有这层意思的。

非AMD模块输出,将非标准的AMD模块"垫"成可用的模块,例如:在老版本的jquery中,是没有继承AMD规范的,所以不能直接require["jquery"],这时候就需要shim,比如我要是用老版本jquery类库,但是他并没有实现AMD规范,那我们可以这样配置

require.config({
    baseUrl: "javascript",
    //packages: [‘carousel‘],
    paths: {
        jquery: ‘lib/jquery.1.6‘,
        bootstrap: ‘lib/bootstrap‘

    },
    shim: {
        "jquery" : {
            exports : "$"
        }
    }

});

这样配置后,我们就可以在其他模块中引用jquery模块:

require([‘jquery‘], function ($) {

    //do something....
});

5.define方法:定义模块

define方法用于定义模块,RequireJS要求每个模块放在一个单独的文件里。

按照是否依赖其他模块,可以分成两种情况讨论。第一种情况是定义独立模块,即所定义的模块不依赖其他模块;第二种情况是定义非独立模块,即所定义的模块依赖于其他模块。

(1)独立模块(代码示例math.html)

如果被定义的模块是一个独立模块,不需要依赖任何其他模块,可以直接用define方法生成。

define({
    method1: function() {},
    method2: function() {},
});

另一种等价的写法是,把对象写成一个函数,该函数的返回值就是输出的模块。

// math.js
  define(function (){
    var add = function (x,y){
      return x+y;
    };
    return {
      add: add
    };
  });

(2)非独立模块
如果被定义的模块需要依赖其他模块,则define方法必须采用下面的格式。

define([‘module1‘, ‘module2‘], function(m1, m2) {
   ...
});

define方法的第一个参数是一个数组,它的成员是当前模块所依赖的模块。比如,[‘module1‘, ‘module2‘]表示我们定义的这个新模块依赖于module1模块和module2模块,只有先加载这两个模块,新模块才能正常运行。一般情况下,module1模块和module2模块指的是,当前目录下的module1.js文件和module2.js文件,等同于写成[‘./module1‘, ‘./module2‘]。

思考? 如果新模块同属于module文件下,如何定义引入文件路径(module.html)参考

define方法的第二个参数是一个函数,当前面数组的所有成员加载成功后,它将被调用。它的参数与数组的成员一一对应,比如function(m1, m2)就表示,这个函数的第一个参数m1对应module1模块,第二个参数m2对应module2模块。这个函数必须返回一个对象,供其他模块调用。

define([‘module1‘, ‘module2‘], function(m1, m2) {

    return {
        method: function() {
            m1.methodA();
            m2.methodB();
        }
    };

});

需要注意的是,回调函数必须返回一个对象,这个对象就是你定义的模块。

如果依赖的模块很多,参数与模块一一对应的写法非常麻烦。

define(
    [       ‘dep1‘, ‘dep2‘, ‘dep3‘, ‘dep4‘, ‘dep5‘, ‘dep6‘, ‘dep7‘, ‘dep8‘],
    function(dep1,   dep2,   dep3,   dep4,   dep5,   dep6,   dep7,   dep8){
        ...
    }
);

为了避免像上面代码那样繁琐的写法,RequireJS提供一种更简单的写法。

define(
    function (require) {
        var dep1 = require(‘dep1‘),
            dep2 = require(‘dep2‘),
            dep3 = require(‘dep3‘),
            dep4 = require(‘dep4‘),
            dep5 = require(‘dep5‘),
            dep6 = require(‘dep6‘),
            dep7 = require(‘dep7‘),
            dep8 = require(‘dep8‘);

            ...
    }

});

6.require方法:调用模块

require方法用于调用模块。它的参数与define方法类似。

1.普通加载方式参见(demo.html)
require([‘jquery‘,‘bootstrap‘], function ($) {
    $(‘.carousel‘).carousel({
        interval: 3000
    });
});

上面方法表示加载jquery和bootstrap两个模块,当这两个模块都加载成功后,执行一个回调函数。该回调函数就用来完成具体的任务。require方法的第一个参数,是一个表示依赖关系的数组。
但是页面往往不会只有一个交互效果,如果多了就会展示这样

require([‘jquery‘,‘bootstrap‘], function ($) {

    $(‘.carousel‘).carousel({
        interval: 3000
    });
});
//收藏方法
require([‘jquery‘], function ($) {

    var collect=$(‘.goodsOffer-collect‘);
    collect.on(‘collect‘,function(){
        if(!collect.hasClass(‘goodsOffer-collect--bg‘)){
            collect.addClass(‘goodsOffer-collect--bg‘);
            collect.html(‘已收藏‘);
        }else{
            collect.removeClass(‘goodsOffer-collect--bg‘);
            collect.html(‘收藏店铺‘);
        }
    })
    collect.on("click",function(){
        $(this).trigger(‘collect‘);
    })
});
//出价控制
require([‘jquery‘,‘sp-bid-control‘], function ($) {

    $(".bidderOffer").spBidControl({
        //步长100
        step : 100,
        //不能点击为false
        isDisabled : false,
        //最大值
        maxVal : 500,
        //最小值
        minVal : 0,
        //当前值
        currVal : 0,
        //可编辑性
        isEdit : false,
        isBtnShow : true,
        //按钮样式
        btnStyle : {
            "btnTxt" : "出价", //我要拍
            "btnCss" : "bidderOffer-btn"
        },
        callbackFn : function(currVal, $element, spBidControl) {
            var $chujiaSubmit = $element.find(".chujia-submit");
            // $chujiaSubmit.off("clik.spBidControl");
            // 不能调用currVal这个值作为出价框数值,会出现出价不成功的情况
            var inputPrice = $(".bidderOffer-text").val();
            console.log(inputPrice);

        }
    });
    setTimeout(function() {
        $(".bidderOffer").spBidControl({
            isDisabled : true,
            btnStyle : {
                "btnTxt" : "已结束", //出价
                "btnCss" : "bidderOffer-btn"
            }
        });

    }, timeParm);
});
//导航菜单的显示隐藏
require([‘jquery‘], function ($) {

    $(‘.outletHeader-menu‘).on(clik,function(){
        $(‘.menu-content‘).toggle();
        return false;
    })
    $(document).on(clik,function(){
        $(‘.menu-content‘).hide();
    });

    $(‘.closeme‘).on(clik,function(){
        $(this).parents(‘.numtips‘).hide();
    });
});

这只是作为参考,目的是为了展示当交互多了的时候会感觉比较乱。参考(demo1.html),为了解决这个问题,引入了包加载模块。

2.包模块加载(参考index.html)

RequireJS支持从CommonJS包结构中加载模块,但需要一些额外的配置。具体地,支持如下的CommonJS包特性:
一个包可以关联一个模块名/前缀。
package config可为特定的包指定下述属性:
name: 包名(用于模块名/前缀映射)
location: 磁盘上的位置。位置是相对于配置中的baseUrl值,除非它们包含协议或以“/”开头
main: 当以“包名”发起require调用后,所应用的一个包内的模块。默认为“main”,除非在此处做了另外设定。该值是相对于包目录的。

require.config({
    baseUrl: "javascript",
    packages: [‘carousel‘],
    paths: {
        jquery: ‘lib/jquery.min‘,
        bootstrap: ‘lib/bootstrap‘

    }
});

//轮播引用
require([‘carousel‘]);

在配置文档中不在进行任何操作,只是定义了一个 packages: [‘carousel‘],然后在配置后将其加载。这时在所定义的根目录下应有一个为carousel的文件夹,里边的文件通常命名为main.js。
在此main.js中将对引入的插件进行相应操作,具体代码示例如下.

require([‘jquery‘, ‘bootstrap‘], function ($) {
    $(‘.carousel‘).carousel({
        interval: 3000
    });
});

看起来似乎和普通调用方法没什么区别,但它确实有几个优势
1.模块与插件直接关系更明确,更易于查找。
2.复用性更好,更容易实现模块化。
3.管理维护起来更加方便。
现在存在这么一个问题,如果多个页面都调用此插件,则会导致main.js中多加载一些代码(当然也可忽略),其实有一个方法可以避免加载更多的代码
我们可以这样配置

require.config({
    packages: [
        "carousel",
        {
            name: "carousel",
            main: "carousel"
        }
    ]
});

减少麻烦期间,强烈建议包结构遵从“main.js”约定。

require合并

运行命令node r.js -o build.js(本次只做简要演示,后期可能专门对其分享)

实例列表

为了方便起见,后面html省略
1.标准包require.js加载(index)
2.普通require.js加载(demo)
3.普通require.js加载(demo1,意在说明此种方式的不足)。
4.特殊包require.js加载(carouse)
5.使用require.js可以不放入$(function(){})(findElements)
6.展示方法重复时函数会覆盖(func)
7.require.js因为方法执行包中故不会覆盖(func2)
8.原始js引入方式(initial,意在说明原始加载的不足)
9.单独依赖的代码事例(math)
10.非独立模块(module)
11.shim针对老版本jquery(shim);
12.shim针对老版本underscore(underscore);

参考文档

1.require官网
2.require.js中文网
3.Javascript模块化编程
4.JS模块化工具requirejs教程
5.RequireJS和AMD规范

 

requireJS使用

标签:

原文地址:http://www.cnblogs.com/Leo_wl/p/4714122.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!