RequireJS入门指导 (转)

最近在百度实习做的一个项目用到了 Require JS 这个库,之前从来没有了解过,经过一番大概的搜索后找到一篇非常不错的文章,看完后能够让你对 Require JS 的运行机制、使用方法以及为什么使用 Require JS 有一个基础的认识。下面我就对这篇文章进行一个简单的翻译,如果有错漏的地方希望指正。

原文链接:http://undefinedblog.com/primer-for-require-js/

谁适合读这篇文章

对 JavaScript 有一定的了解,写过一定规模的 JavaScript 代码,尤其能够掌握 JavaScript 匿名函数、回调等概念,并希望了解 Require JS 的用法、概念、意义等。

一些基本信息

Require JS(官网) 是一个 JavaScript 文件或模块的加载器,它可以根据不同页面对不同模块的需求,按照你的设置依次加载并执行所有的 JavaScript 文件。使用 Require JS 主要有两个目的:

  • 解耦代码,方便代码重用和管理
  • 加速页面加载,内置优化引擎(需服务器支持),自动异步加载依赖项,将所有需要加载的文件自动合并为一个文件,减少 HTTP 请求

Require JS 同时支持整合 jQuery、CommonJS、Node JS 等,而且对浏览器有不错的兼容性(IE 6+,你懂的)。

没有 Require JS 的时候

下面我们将以一个没有使用 Require JS 的模块开始,讲讲如何将你的代码解耦并使用 Require JS 来加载:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Phase 1</title>
</head>
<body>
    <div>
        <h1>Modular Demo 1</h1>
    </div>
    <div id="messagebox"></div>

    <script src="../Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script type="text/javascript">

        var baseUrl = ‘/api/messenger/‘;

        function ShowMessage(id) {
            $.ajax({
                url: baseUrl + id,
                type: ‘GET‘,
                dataType: ‘json‘,
                success: function(data) {
                    $("#messagebox").html(data);
                }
            });
        }

        var id = 55;
        ShowMessage(id);

    </script>
</body>
</html>

以上是一个很简单而且很常见的 ajax 请求页面,可以看到这个页面里的代码虽然简单,但是耦合度很高,下面我们将其中的 JavaScript 代码解耦,把不同的模块独立出来。

//模块1,全局设置模块
        var config = (function() {
            var baseUrl = ‘/api/messenger/‘;

            return {
                baseUrl: baseUrl
            };
        })();

//模块2,请求数据模块
        var dataservice = (function($, config) {
            var callApi = function (url, type, callback) {
                    $.ajax({
                        url: url,
                        type: type,
                        dataType: ‘json‘,
                        success: function (data) {
                            callback(data);
                        }
                    });
                },
                getMessage = function (id, callback) {
                    url = config.baseUrl + id;
                    callApi(url, ‘GET‘, callback);
                };

            return {
                getMessage: getMessage
            };
        })($, config);

//模块3,封装的一个 messenger 模块,显示 ajax 放回的数据
        var messenger = (function ($, dataservice) {
            var showMessage = function(id) {
                dataservice.getMessage(id, function(message) {
                    $("#messagebox").html(message);
                });
            };

            return {
                showMessage: showMessage
            };
        })($, dataservice);

//模块4,匿名函数,传 id, 调用 messenger 的showMessage() 方法 (直接执行)
        (function (messenger) {
            var id = 55;
            messenger.showMessage(id);
        })(messenger);

将这些代码放到原来的、没有重构前的页面中去,将实现同样的效果。但是我们将这些功能独立出来后,就可以很好的重复利用部分代码。

下面假设我们将这 4 个模块放到 4 个独立的 js 文件中:

  • 模块1:config.js
  • 模块2:dataservice.js
  • 模块3:messenger.js
  • 模块4:main.js

这样,在我们的 html 页面中,我们需要依次加载这 4 个模块:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Phase 1</title>
</head>
<body>
    <div>
        <h1>Modular Demo 1</h1>
    </div>
    <div id="messagebox"></div>

    <script src="../Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script src="config.js" type="text/javascript"></script>
    <script src="dataservice.js" type="text/javascript"></script>
    <script src="messenger.js" type="text/javascript"></script>
    <script src="main.js" type="text/javascript"></script>

</body>
</html>

这个时候,代码一样可以工作的非常顺利,没有任何问题。但是需要考虑一个问题:js 文件的加载顺序。当一个模块2需要依赖模块1中的功能时,必须要求模块1加载完成后再执行模块2中的代码。对于简单的代码(如本文涉及的仅4个模块)还好考虑,若有数十个模块需要加载,那么依赖的顺序一旦处理出错,很可能就会报 xxx is undefined 错误。

这个时候就是 Require JS 需要大显身手的时候。

Require JS 的基础操作

定义模块

define([‘jquery‘],
    function ($) {
        var text = ‘I am a module‘,
            showMessage = function() {
                $("#messagebox").html(text);
            };

        return {
            showMessage: showMessage
        };
    }
);

可以看到,一个 JavaScript 模块(如上面提到的 config、dataservice、messenger 等),都被一个 define() 函数包起来。

其中 define() 函数接受 3 个参数:

  • 模块名
  • 依赖项,以数组形式传递
  • 模块内容

但是注意,上面的模块定义中,我们并没有传 模块名 这个参数,理由如下:

Require JS 会自动根据文件名(不含后缀名,即不含 ".js")来给定义的模块命名,这样在最后优化(将所有的 js 文件合并为一个)时就能自动调用所有的文件。如果你显示的给定义的一个模块命名了,那么在日后进行修改时(比如改动了文件名或模块名),Require JS 将无法自动加载。因此最佳实践是:不要显式的定义模块名,让文件名成为默认的模块名,方便 Require JS 管理。

说完了第一个参数,再看看第二个参数 依赖项。依赖项我们传递的是一个字符串数组,每个字符串均代表要实现本模块的功能,需要预先加载的其他模块的模块名。如上例中我们的依赖项就是 jquery。

最后一个参数就是我们需要定义的模块内容。在上例中,我们的模块是一个 function,其中函数的形参即为对依赖项的引用。比如我们的模块有两个依赖项:

define([‘moduleA‘,‘moduleB‘],function(a,b){
        //a.blabla(); b.blabla = ooxx;
});

就可以在模块中分别使用形参来调用我们依赖的模块。需要注意的一点是,依赖项的书写顺序和在模块定义的函数中的形参顺序要一致。

另外,Require JS 定义的模块并不一定是 function,也可以是普通的对象,详见 Require JS 文档

将解耦后的代码改写为 Require JS 模块

我们在上面把一个简单的 ajax 调用解耦成 4 个独立的模块,下面我们就把这 4 个模块根据 Require JS 定义模块的风格进行改写。

//config.js
define([],
    function () {
        var baseUrl = ‘/api/messenger/‘;

        return {
            baseUrl: baseUrl
        };
    }
);

//dataservice.js
define([‘jquery‘, ‘config‘],
    function ($, config) {
        var
            callApi = function (url, type, callback) {
                $.ajax({
                    url: url,
                    type: type,
                    dataType: ‘json‘,
                    success: function (data) {
                        callback(data);
                    }
                });
            },

            getMessage = function (id, callback) {
                url = config.baseUrl + id;
                callApi(url, ‘GET‘, callback);
            };

        return {
            getMessage: getMessage
        };
    }
);

//messenger.js
define([‘jquery‘, ‘dataservice‘],
    function ($, dataservice) {
        var showMessage = function (id) {
            dataservice.getMessage(id, function (message) {
                $("#messagebox").html(message);
            });
        };

        return {
            showMessage: showMessage
        };
    }
);

//main.js
(function() {
    requirejs.config(
        {
            paths: {
                ‘jquery‘: ‘../Scripts/jquery-1.8.2.min‘
            }
        }
    );

    require(
        [‘messenger‘],
        function(messenger) {
            var id = 55;
            messenger.showMessage(id);
        }
    );
})();

你可能注意到了 main.js 中定义模块的方式似乎不同于其它 3 个模块。没错,因为严格意义上来说,main.js 是调用了其它 3 个模块的功能并最终获得数据。因此下面就要引出怎么在定义了 Require JS 模块后最终设置和调用的问题。

设置和调用模块

Require JS 对于模块的设置和调用提供了两种方式:

1、定义一个 script 标签,并增加 data-main 属性,指向我们的设置文件;同时添加 src 属性,指向 require-js.js 文件(即主库)

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

2、先引入 Require JS 库,再显式的设置

<script src="require-js.js"></script>
<script>
require({
        baseUrl : ‘scripts‘, //设置查找所有模块的根目录
        paths:‘‘,//如果在 baseUrl 下没有找到相应的模块,则加上 paths 继续查找
        shim:{},//加载依赖项,传对象
});
require([‘dataservice.js‘]); //加载完上述所有依赖项后,再加载自己编写的模块
</script>

详细参数见 Require JS 文档

以上就是 Require JS 的一些简单使用方法和实践,话再说回 iOS 开发……很快回归!

文件:r9.zip

时间: 2024-08-24 21:32:22

RequireJS入门指导 (转)的相关文章

新手入门指导:Vue 2.0 的建议学习顺序

起步 1. 扎实的 JavaScript / HTML / CSS 基本功.这是前置条件. 2. 通读官方教程 (guide) 的基础篇.不要用任何构建工具,就只用最简单的 <script>,把教程里的例子模仿一遍,理解用法.不推荐上来就直接用 vue-cli 构建项目,尤其是如果没有 Node/Webpack 基础. 3. 照着官网上的示例,自己想一些类似的例子,模仿着实现来练手,加深理解. 4. 阅读官方教程进阶篇的前半部分,到『自定义指令 (Custom Directive) 』为止.着

Web开发的入门指导

Web开发的入门指导 web开发 编程技术 你点开此文,说明你对Web开发是有兴趣的,或者你正在思考开始学习Web开发.在这里,我会告诉你成为一名Web开发者的路线,是对初学者关于Web开发的指导.这篇文章不会教你如何写代码,而是指出在你在真正写代码之前要思考的事情.Web开发是令人兴奋和有激情的事情,正是迎合了这个高速变化发展的世界.了解Web开发,我们先来定义几个基本的概念. 前段和后端 一开始一定要分清前端开发和后端开发,我们来分别介绍一下. 前段 Web应用被分类归为分布式应用,一般是客

requirejs入门知识整理

使用模块化开发处理的三大问题: 1.命名冲突:2.繁琐的文件依赖 3.实现异步非阻塞的文件加载,避免网页失去响应 模块化的设计使得JavaScript代码在需要访问“全局变量”的时候,都可以通过依赖关系,把这些“全局变量”作为参数传递到模块的实现体里,在实现中就避免了访问或者声明全局的变量或者函数,有效的避免大量而且复杂的命名空间管理. requirejs以一个相对于baseUrl的地址来加载所有的代码.如果用了data-main属性,则该路径就是baseUrl,baseUrl亦可通过requi

RequireJS入门

RequireJS由James Burke创建,他也是AMD规范的创始人. RequireJS会让你以不同于往常的方式去写JavaScript.你将不再使用script标签在HTML中引入JS文件,以及不用通过script标签顺序去管理依赖关系. 当然也不会有阻塞(blocking)的情况发生.好,以一个简单示例开始. 新建一个目录,结构如下 目录r1下有index.html.jquery-1.7.2.js.main.js.require.js.require.js和jquery-1.7.2.j

RequireJS入门(三)

这篇来写一个具有依赖的事件模块event.event提供三个方法bind.unbind.trigger来管理DOM元素事件. event依赖于cache模块,cache模块类似于jQuery的$.data方法.提供了set.get.remove等方法用来管理存放在DOM元素上的数据. 示例实现功能:为页面上所有的段落P元素添加一个点击事件,响应函数会弹出P元素的innerHTML. 创建的目录如下 为了获取元素,用到了上一篇写的selector.js.不在贴其代码. index.html 如下

[Zephir官方文档翻译之五] 入门指导

入门指导 Zephir还有这本手册,是为了PHP开发者想开发C扩展并降低复杂度面打算的. 我们假设你有编程语言的基础.我们会在介绍的时候尽可能的向PHP,C,Javascript等语言的特点来陈述. 如果你懂得这些语言中的某一种的话,我们会指出它们来Zephir的相似点.当然其它的一些Zephir的新特性还有 不同点我们也会一一介绍. 检测安装情况 如果你成功的安装了Zephir,你可以在命令行中执行下面的命令: $ zephir help 如果安装正确的话,你会看到下面的提示:  _____ 

RequireJS入门(一)

RequireJS由James Burke创建,他也是AMD规范的创始人. RequireJS会让你以不同于往常的方式去写JavaScript.你将不再使用script标签在HTML中引入JS文件,以及不用通过script标签顺序去管理依赖关系. 当然也不会有阻塞(blocking)的情况发生.好,以一个简单示例开始. 新建一个目录,结构如下 目录r1下有index.html.jquery-1.7.2.js.main.js.require.js.require.js和jquery-1.7.2.j

RequireJs入门1

RequireJs入门 随着Javascript在开发中占得比重越来越大,就需要一个团队来分工.协作,为了大家的代码可以更好的相互使用,这个时候模块化编程 就成为一个迫切的需求了.但是Javascript本身不是模块化的语言.它不支持类,更别说模块了. 既然模块如此重要,那团队开发中就应该去制定一种规范,来约束大家,这样就便于大家相互使用.如果每个人都按自己的写法,那肯定是乱了套的, 目前Javascript官方没有规范,通行的Javascript模块规范只有两种:CommonJs和AMD Co

React-Native入门指导之iOS篇 —— 一、准备工作

React-Native 入门指导系列教程目录 一.准备工作 (已完成) 二.项目介绍与调试 三.CSS样式与Flex布局 四.常用UI控件的使用 五.JSX在React-Native中的应用 六.事件与数据调用 七.自定义组件 八.动手写实例 九.发布与真机调试 写在前面 1. 什么是React-Native? React-Native是:Facebook 在2015年初React.js技术研讨大会上公布的一个开源项目.支持用开源的JavaScript库React.js来开发iOS和Andro