RequireJS 是一个 JavaScript 的文件和模块加载器,RequireJS 针对浏览器做了特别优化,但也可以在其它环境运行,例如:Rhino 和 Node。现在的网页基本上都是使用模块化开发,ES 6 原生支持模块化,加载模块也比较方便,但现在还有一部分浏览器还不支持 ES 6,例如 IE 系列。如果你的网页不想用 ES 6 开发的话使用 RequireJS 加载模块是一个不错的选择。

兼容性

下面是 RequireJS 的浏览器兼容情况:

IEFirefoxSafariChromeOpera
6+2+3.2+3+10+

下载 & 引入

点击此处 进入 RequireJS 官网 下载 RequireJS,点击 下载 后浏览器可能会直接打开 JS 页面,按 ctrl + s 保存。

在很早以前引入 JS 文件应该是这样的:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<script type="text/javascript" src="js/function.js"></script>
<script type="text/javascript" src="js/main.js"></script>

需要严格遵守依赖顺序,而且文件多了可能还会阻塞渲染。

使用 RequireJS 后 HTML 中只需要引入 RequireJS 和入口文件,下面是一个超简单的 HTML 项目目录:

D:.
│  test1.html
│
└─js
        main.js
        rand.js
        require.js

在 HTML 文件中引入 require.jsmain.js

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

入口文件需要写在 data-main 属性中,data-main 加载的文件的 js 后缀可以省略。你还可以给 script 标签加入 async 属性,对于 IE 以外的浏览器可以异步执行 JS,如果要详细了解 async 属性可以 点此进入 W3Scrool

加载文件和模块

上面在 HTML 中加载了 require.jsmain.js ,在 main.js 中又可以调用 RequireJS 加载文件,下面在 main.js 中加载 rand.js ,这个 rand.js 是一个生成随机数的函数,下面是 rand.js 中的内容:

function rand(max, min) {
    var num = max - min;
    return Math.round(Math.random() * num + min);
}

加载 rand.js

requirejs(['js/rand.js'], function() {
    //  调用 rand.js 中的 rand 函数
    var randNum = rand(100, 50);
    //  在控制台输出内容
    console.log(randNum);  //  71
});

上面的加载都是异步加载的,不会影响其它 JS 代码的执行。使用 requirejs() 函数加载 JS 文件,第 1 个参数就是要加载的文件,需要传入一个数组,可加载多个文件,第 2 个参数是一个回调函数,在回调函数中可以调用模块中的功能。

加载 jQuery 也是可以的,下面加载一个线上的 jQuery

requirejs([
    'https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js'
], function() {
    $('button').on('click', function() {
        alert('Hello RequireJS');  //  点击按钮弹出对话框
    });
});

加载 jQuery 和 rand.js

requirejs([
    'https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js',
    'js/rand.js'
], function() {
    //  鼠标点击
    $('button').on('click', function() {
        alert(rand(1000, 9999));  //  显示随机数
    });
});

定义模块

模块和一般的脚本文件相比有一个比较好的地方就是模块的函数和对象不会污染全局命名空间,只有在引入模块的回调函数中才能使用模块的功能。

键值对模块

如果你的模块不需要依赖其他文件或模块的话,可以使用 JSON 键值对的方式来定义模块,如下:

define({
    userName: 'Mister Ma',
    email: 'email@misterma.com',
    showInfo: function() {
        console.log('用户名:' + this.userName);
        console.log('邮箱:' + this.email);
    }
});

上面模块的文件名为:user.js ,下面调用 user.js

requirejs(['js/user.js'], function(user) {
    console.log(user.userName);  //  在控制台输出 user 的 userName
    user.showInfo();  //  调用 user 的 showInfo 方法
});

函数模块

下面是一个生成随机数的模块,不依赖其他文件或模块:

define(function() {
    return function(max, min) {
        var num = max - min;
        return Math.round(Math.random() * num + min);
    };
});

上面的模块文件名为:rand.js,下面调用 rand.js

requirejs(['js/rand.js'], function (rand) {
    console.log(rand(1000, 9999));  //  调用 rand 并在控制台输出
});

函数模块可以返回任何你想返回的内容。

包含依赖的函数模块

下面是一个获取浏览器可视区宽度和高度的模块:

define(function() {
    return function() {
        return {
            w: window.innerWidth,
            h: window.innerHeight
        };
    };
});

上面模块的文件名为:size.js,主要功能就是获取浏览器可视区的宽高,下面的模块会依赖上面的 size.js

define(['js/size.js'], function(size) {
    return function() {
        var windowSize = size();
        console.log('宽度:' + windowSize.w);
        console.log('高度:' + windowSize.h);
    };
});

上面模块的文件名为:getWindowSize.js,主要功能就是在控制台输出浏览器可视区的宽高,需要依赖 size.js,下面调用 getWindowSize.js

requirejs(['js/getWindowSize.js'], function(getWindowSize) {
    getWindowSize();  //  调用 getWindowSize 在控制台输出可视区的宽高
});

如果一个模块需要依赖其他模块的话,第 1 个参数就是模块文件名,模块文件名需要传入一个数组。

为了方便管理 建议 1 个文件中只包含 1 个模块。