码迷,mamicode.com
首页 > 编程语言 > 详细

Javascript 模块化编程 --RequireJs

时间:2015-11-11 14:43:15      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:

什么是模块化

模块就是实现特定功能的一组方法

 

常见的几种js写法

 

  • 原始写法

 

        function A() {

        }

        function B() {
            
        }

 

上面函数A()和B()组成一个模块,使用的时候直接调用就行了

缺点: “污染”了全局变量,模块成员之间没有直接的联系。

 

  •   对象写法
var module= {
         count:1,
         A: function() {
         },
         B: function() {
         }
       }

这种写法把变量count和函数A和 B 都封装到了module中,使用的时候直接调用,例如:

Module.A();

缺点:这种做法暴露了模块成员,内部的变量可以被外部改写,例如:

Module.count=5

 

  • 立即执行函数写法

 

var modulel = (function() {
            var count = 5;
            var A = function() {
                console.log("function A");
            };
            var B = function() {
                console.log("function B");
            };
            return {
                A:A,
                B:B,
                count:count
            }

        })();

 

 

  •  放大模式

如果一个模块很大,必须分成几个部分,则需要继承另外一个模块,则有必要使用“放大模式”

 

var commonUtil = (function (util) {

            util.m1 = function () {

                console.log("m1 function");

            };
            util.m2 = function () {
                console.log("m2 function");
            };

            util.count = 5;

            return util;

        })(commonUtil);

        console.log(commonUtil.m1());

        console.log(commonUtil.count);
  •  宽放大模式
var commonUtil = (function (util) {
            util.m1 = function () {
               console.log("m1 function");
            };
            util.m2 = function () {
                console.log("m2 function");
            };

            util.count = 5;

            return util;

        })(commonUtil || {});

        console.log(commonUtil.m1());

        console.log(commonUtil.count);

与“放大模式”相比,“宽放大模式”就是立即执行函数可以是空对象

 

 

为什么要用require.js

最早的时候,所有的javascript都是写在一个文件中,代码越来越多,则分成了多个,例如:

<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>
<script src="5.js"></script>
<script src="6.js"></script>

这样做的缺点:

1)加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就越长

2)必须保证加载的顺序,依赖最大的模块一定要放到最后加载

 

Require.js就是为了解决这两个问题: 

1)   实现js文件的异步加载,避免网页失去响应

2)   管理模块之间的依赖性,便于代码的编写和维护

 

Require.js加载

首先要到官方网站下载最新版本http://requirejs.org/docs/download.html放到Scripts目录下

然后在页面加载,例如:

<script src="Scripts/require.js"></script>

 

加载这个文件也有可能造成网页失去响应,解决办法有两个,一是把它放在网页底部加载,另外一个是写成这样:

<script src="Scripts/require.js" defer async="true" ></script>

Async表示是异步加载,ie不支持这个属性,只支持defer,所以把defer也写上

 

加载require.js之后,则是加载我们自己的代码了,假如我们自己的代码文件是main.js,则需要写成这样

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

 

data-main属性的作用是指定网页程序的主模板,就是网页的入口代码,有点像控制台程序的main()函数,所有的代码都是从这里开始运行

 

模块的加载

假如模块依赖’jquery’,’underscore’,’backbone’,则需要在require.config()方法中对这些模块进行配置

我们可以把require.config()写在主模块main.js的头部,也可以新建一个require_config.js文件把这些配置写在这个文件中,然后在页面引用这个文件,例如:

 

(function () {
    var baseurl = "/Scripts/";
    require.config({
        paths: {
            "jquery": baseurl+"jquery",
            "underscore": baseurl+"underscore",
            "backbone": baseurl+"backbone",
            "index":baseurl+"lib/index"
        },

        shim: {
            ‘underscore‘: {
               exports: ‘_‘
            },

            ‘backbone‘: {
                deps: [‘underscore‘, ‘jquery‘],
                exports: ‘Backbone‘
            }
        }

    });
})();

 

如果某个模块在另外的主机上,也可以指定网址,例如:

require.config({
        paths: {
            "jquery":”https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min”,    
        }
    });

require.js加载的模块,必须按照AMD规范,用define()函数定义的模块。但有一部分函数库并不符合这种规范,这种模块则必须在require()加载前,用shim属性进行配置,shim属性是用来配置不兼容的模块。

例如:

   shim: {
            ‘underscore‘: {
                exports: ‘_‘
            },

            ‘backbone‘: {
                deps: [‘underscore‘, ‘jquery‘],
exports:
‘Backbone‘ } }

 

其中

1) exports表示输出变量名,即在模块外部调用的名称

2) deps数组,表示该模块的依赖性

 

 

 

主模块的写法

require()函数接受两个参数,第一个参数是一个数组,表示所依赖的模块,第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数的形式传入该函数,而在回调函数中就可以使用这些模块了。

例如:主模块依赖jquery,underscore和backbone这三个模块,main.js就可以这样写:

 

require ([‘jquery‘, ‘underscore‘, ‘backbone‘], function ($, _, Backbone) {
   //some code here
});

require.js会先加载jQuery,underscore和backbone,然后再运行回调函数,主模块的代码就写在回调函数中

 

AMD模块的写法

require.js加载的模块,采用AMD规范,模块也必须按照AMD来写,就是模块必须采用特定的define函数来定义,例如index.js:

技术分享
define([‘jquery‘, ‘underscore‘, ‘backbone‘], function ($, _, Backbone) {

    var listView = {

        World: Backbone.Model.extend({

            name: null

        }),

 

        Worlds: Backbone.Collection.extend({

            initialize: function(models, options) {

                this.bind("add", options.view.addOneWord);

            }

        }),

 

        AppView: Backbone.View.extend({

            el: $("body"),

            initialize: function() {

                this.worlds = new listView.Worlds(null, { view: this });

            },

            events: {

                "click #check": "checkIn"

            },

 

            checkIn: function() {

                var world_name = prompt("请问你是哪里人");

                if (world_name == "") world_name = "未知";

                var world = new listView.World({ name: world_name });

                this.worlds.add(world);

            },

 

            addOneWord: function (model) {

                $("#world-list").append("<li>我是来自:" + model.get("name") + "的人!</li>");

            }

        })

    };

 

 

    return listView;

 

});
View Code

 

然后在require_config.js的path中进行定义,例如:

(function () {

    var baseurl = "/Scripts/";

    require.config({

        paths: {
            "index":baseurl+"lib/index"
        },
    });
})();

 

之后再在页面对这个index模块进行加载,如:

 

require([‘index‘], function(indexView) {

            var app = indexView.AppView;

            var AppView = new app; 

        });

 

Define和require在依赖处理和回调执行上是一样的,但是define回调的函数需要有return语句返回模块对象,这样define定义的模块才能被其他模块调用;require回调函数不需要有return语句。

 

所以说define和require都可应用来加载和使用模块,但是define可以用来定义模块,用define定义的模块必须要有返回值

Javascript 模块化编程 --RequireJs

标签:

原文地址:http://www.cnblogs.com/alice626/p/4955961.html

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