Awesome Open Source
Awesome Open Source

RequireJS

require.js加载js文件的好处

  1. 可以防止JS加载时候阻塞页面渲染(JS运行时候DOM停止渲染的情况)
  2. 使用require.js调用的方式加载JS,不用在像以前那样多个<script>标签引入JS文件

所有代码的目录结构如图

这里写图片描述

代码存放的Github地址

传统的引入

start.html

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="js/require.js"></script>
    <script type="text/javascript" src="js/a.js"></script>
</head>
<body>
    <p>wsscat</p>
</body>
</html>

传统方法引入可以看到会先弹出alert,内容被阻塞没有渲染

a.js

function cat() {
    alert("hello");
}
cat();

require.js的引入

start.html

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="js/require.js"></script>
    <script>
        require(["js/a"]);
    </script>
</head>
<body>
    <p>wsscat</p>
</body>
</html>

a.js

define(function () {
    function cat() {
        alert("hello");
    }
    cat();
})

现在应require里面写可以避免以前的写法导致alert弹窗时候页面的p标签内容被阻塞无法渲染

现在这种写法格式是用define定义一个模块,并在页面中调用require方法引入

要注意的是,require接受的是一个数组,它注入的依赖是一个数组,哪怕数组只有一个依赖,而它第二个参数则可以传入一个回调函数,就是党数组中的依赖都加载完毕后,执行这个回调函数,比如我们可以加载jQuery的依赖,然后再回调函数中调用jQuery的库

require(["js/a"]);

config方法

我们可以在上面代码上继续改进,可以用require.js的config方法,通过paths属性,就不用每次都写这么长的引入地址,有点像angular的服务注册,然后在控制器中注入相应的服务

base.js

require.config({
    paths: {
        "jq": ["http://wsa.wsscat.com/jquery", "js/jquery"],
        "a": "js/wsscat"
    }
})

注意加载模块时不用写.js后缀,写了会报错 我们可以把配置这样引入到主页里面

<script type="text/javascript" src="js/require.js"></script>
<script type="text/javascript" src="js/base.js"></script>

##path属性 用paths还有一个好处就是让我们配置多个路径去加载js,当我们请求第一个路径不成功时候,可以继续往后面请求第二个js路径代替 这里写图片描述

##data-main 我们还可以这样引入,在require引入的script标签中加入data-main属性,后面就不用在显式用<script>标签引入其他脚本文件了

<script type="text/javascript" data-main="js/base" src="js/require.js"></script>

base.js

require.config({
    baseUrl: 'js',
    paths: {
        jq: ["http://wsa.wsscat.com/jquery", "jquery"],
        a: "wsscat"
    }
})
require(["jq", "a"], function () {
    $('span').css('color', '#673AB7');
});

可以看到已经成功加载到我们所需要的依赖了 这里写图片描述

RequireJS的模块语法允许它尽快地加载多个模块,虽然加载的顺序不定,但依赖的顺序最终是正确的,就是说模块是异步不按顺序加载,但使用的时候只要依赖的顺序正确那就会按依赖摆放的顺序执行

上面我们可以把之前的代码改进成这样,用define采用AMD规范,把方法写进模块里面,并以对象传递出来 wsscat.js

define(
    function () {
        function fun1() {
            alert("wsscat");
        }

        function fun2() {
            alert("autumns");
        }
        return {
            f1: fun1,
            f2: fun2
        }
    }
)

base.js

require.config({
    baseUrl: 'js',
    paths: {
        jquery: ["http://wsa.wsscat.com/jquery", "jquery"],
        a: "wsscat"
    },
})
require(["jquery", "a"], function ($, a) {
    console.log($('span'));
    $('span').css('color', '#673AB7');
    console.log(a);
});

然后注入a的JS,并依赖此服务,是输出a,就能看到我们刚才模块给的对象里面的两个函数

这里写图片描述

模块依赖另一个模块

如果我们在一个依赖中还要再去依赖另一个JS,理解来相当于angular在服务中还需要注入其他服务来扩展 我们就可以继续这样改,在define中加入一个数组,让我们想把需要的依赖给填充进去,记得回调函数里面需要把这个依赖也加进去形参里面 wsscat.js

define(['wsscat2'],
    function (wsscat2) {
        function fun1() {
            alert("wsscat");
        }

        function fun2() {
            alert("autumns");
        }

        return {
            f1: fun1,
            f2: fun2,
            f3: wsscat2.f1
        }
    }
)

wsscat2.js

define(
    function () {
        function fun1() {
            return "wsscat2.js's wsscat";
        }

        function fun2() {
            return "wsscat2.js's autumns";
        }
        return {
            f1: fun1,
            f2: fun2
        }
    }
)

上面我们就完成了wsscat这个模块依赖了wsscat2模块,然后再次输出新的对象方法

这里写图片描述

shim(非AMD写法的兼容)导入单个变量

当我们遇到非AMD兼容写法的时候,我们要可以用exports方法,注意的是export方法只能输出一个方法或者对象 base.js

require.config({
    //可以把下面共同指向js文件夹写在这个位置
    baseUrl: 'js',
    //path可以让我省略冗长的地址信息
    paths: {
        //可以配置多个路径,当js请求不成功,可以有备选路径
        jquery: ["http://wsa.wsscat.com/jquery", "jquery"],
        //define中再依赖其他模块
        a: "wsscat",
        //define遵从AMD的写法
        b: "wsscat2",
        //export一个对象
        c: "wsscat3",
        //export一个函数
        d: "wsscat4"
    },
    //非AMD规范时候的兼容写法
    //export暴露出对应的对象和方法
    shim: {
        c: {
            //导出对象
            exports: "obj",
        },
        d: {
            //导出方法
            exports: "fun4"
        }
    }
})
//注入对应依赖,当依赖都请求成功后执行对应的回调函数
require(["jquery", "a", "c", "d"], function ($, a, c, d) {
    console.log($('span'));
    $('span').css('color', '#673AB7');
    console.log(a.f3());
    console.log(c);
    console.log(d);
});

wsscat3.js

function fun1() {
    return "wsscat3.js's wsscat";
}

function fun2() {
    return "wsscat3.js's autumns";
}
var obj = {
    f1: fun1,
    f2: fun2
}

wsscat4

function fun4() {
    return "wsscat4.js's wsscat";
}

上面我们就可以用exports方法分别把wsscats3和wsscat4里面的对象和方法暴露出来了

init(非AMD写法的兼容)导入多个变量

e: {
    init: function() {
        return {
            fun5: fun5,
            fun6: fun6
        }
    }
}

我们可以用init方法来导入多个变量,比shim属性导入单个零活,注意return里面的属性值是没有双引号的

require/text

我们利用text插件为组件引入html和css

使用npm下载require/text模块或者在github中下载text.js文件

npm install requirejs/text

然后在配置文件

require.config({
    baseUrl: 'js',
    paths: {
        text: ["text"],//<-添加这一个模块
        jquery: ["jquery"],
        bsheader: "../extends/bsheader/bsheader",
        bsmain: "../extends/bsmain/bsmain",
        bsfooter: "../extends/bsfooter/bsfooter",
        bsmodal: "../extends/bsmodal/bsmodal"
    }
})

//并注入对应依赖,当依赖都请求成功后执行对应的回调函数
require(["jquery", "text", "bsheader", "bsmain", "bsfooter"], function ($, text, bsheader, bsmain, bsfooter) {
    console.log(text);
    $("bsheader").bsheader();
    $("bsmain").bsmain();
    $("bsfooter").bsfooter();
});

然后我们就可以在组件中这样引入css和html文件了,注意要先插入html到页面再绑定事件,不然事件会失效,并且引入html和css文件时候要记得这样引入text!./bsfooter.htmltext!加上文件路径的名字

define(["jquery", "text!./bsfooter.html", "text!./bsfooter.css"],
    function ($, html) {
        var html = html;
        return $.fn.extend({
            bsfooter: function (option) {
                return this.each(function () {
                    $(this).html(html);
                });
            }
        });
    }
)

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
javascript (70,403
component (570
module (142
amd (50
commonjs (26
requirejs (16