`

JavaScript模块化开发(四) —— RequireJS

阅读更多

本文转载自原地址,感谢Feeldesign Studio的无私分享!

 

RequireJS 是一个JavaScript文件和模块加载器,它主要用于浏览器端,但也可以适用于Rhino / Node 等环境。RequireJS遵循了AMD规范,使用非常广泛。

之前的文章(一)(二)(三)已经介绍了JavaScript模块化开发的一些基础知识和规范。本文主要说一说RequireJS的使用。

获取和开始使用RequireJS

点击这个链接即可下载最新版的RequireJS。

下载之后,把它放在项目的脚本文件夹下,比如 js 文件夹下,项目结构看上去应该是:

要充分使用RequireJS,在 index.html 文件中,应该把所有的内联脚本都移除,只留下一句话: 

<!DOCTYPE html>
<html>
<head>
    <title>My Sample Project</title>
    <!-- data-main 属性告诉 require.js 在 require.js  加载之后加载 js/main.js -->
    <script data-main="js/main" src="js/require.js"></script>
</head>
<body>
<h1>My Sample Project</h1>
</body>
</html>

在 main.js 中,可以通过 require() 加载依赖的脚本,这样不用在 html 中显示声明。main.js 相当于是一个入口点: 

require(["helper/util"], function (util) {
    // 当 scripts/helper/util.js 加载完毕,会执行这个回调函数
    // 如果 util.js 也声明了依赖的文件(模块),那么这个函数会等到那些依赖的文件(模块)加载完毕后才调用
    //TODO
}); 

RequireJS API

加载js文件

通过刚才的介绍,可以看出来 RequireJS 采用了不同于传统 <script> 标签的加载方式,传统的 <script> 标签方式一般都会有下面的代码: 

<body>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.plugin.xx.js"></script>
<script type="text/javascript" src="js/a1.js"></script>
<script type="text/javascript" src="js/a2.js"></script>
<script type="text/javascript" src="js/a3.js"></script>
……
</body>

这样的代码极复杂又难以维护。RequireJS 采用了模块ID的方式替代了通过URL加载脚本的方式,还记得那句声明么: 

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

RequireJS 查找脚本的路径,主要是通过 baseUrl,在 data-main 中,声明了 baseUrl 的路径,在这句代码里也就是 js 文件夹;如果不声明 data-main,则 baseUrl 默认指向这个 html 页面所在的文件夹。当然,也可以通过配置来声明 baseUrl,下文会详述。

注意,data-main 中声明的模块会被异步加载,也就意味着如果页面后面通过 <script> 加载多个脚本,这些脚本不一定在 data-main 中声明的模块加载之后才加载;或者后面的js代码如果有对 data-main 中声明的模块的依赖,则有可能会出现错误。

RequireJS 会假定所有依赖项默认都是脚本,所以书写依赖时可以省略 “.js” 后缀,RequireJS 会自动加上这个后缀。RequireJS 会自动把模块ID翻译成一个路径(path),我们也可以在配置中声明多个路径(paths),通过 baseUrl + paths,可以用很少的代码找到相应的 js 文件,比起 <script> 标签要优雅简洁很多。

一般来说,通过 baseUrl + paths 就可以找到js文件,不过有时候,可能会有例外,一旦 RequireJS 发现模块 ID 中包含如下的字符,那么它就不按照 baseUrl + paths 的方式来寻找这个模块的js文件了,而是采用 URL 的方式:

  • 如果 ID 以 “.js” 结尾
  • 如果 ID 以 “/” 开头
  • 如果 ID 以 “http:” 或者 “https:” 开头

一般来说,最好使用 baseUrl + paths 的方式来声明模块ID,这样做会有更多的灵活性。同样的,我们在组织js代码文件的时候,尽量避免使用很深的路径,而最好把js文件都放置在 baseUrl 下面,最好不要超过两层的深度,下面就是一个很好的例子:

  • www/
    • index.html
    • js/
      • app/
        • sub.js
      • lib/app.js
        • jquery.js
        • canvas.js
      • app.js 

在 index.html 中:

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

在 app.js 中: 

requirejs.config({
    //默认从 js/lib 中加载模块
    baseUrl : 'js/lib',
    //如果模块ID以app开头,则会在 js/app 目录下寻找
    //不过要注意千万不要加上 ".js",否则paths的规则就会失效
    paths : {
        app : '../app'
    }
});
requirejs(['jquery', 'canvas', 'app/sub'],function ($, canvas, sub) {
        //jQuery, canvas 和 app/sub 模块都加载完毕后,会执行这个函数
        //TODO
});

使用RequireJS时,建议像 jQuery 这样带有版本号的库,用单独的文件来标识版本号,在文件命名中把版本号去掉。 

定义模块

RequireJS 要求一个js文件只定义一个模块。不过这样的话,每加载一个模块,就会产生一个HTTP请求,RequireJS 提供了一个优化工具,在最后生产环境中,可以打包所有模块到一个文件中。

定义模块可以使用 define() 方法,define() 有三个参数,可以参考前文中的介绍 

定义一个只有键值对,没有任何依赖的模块: 

define({
    color : "black",
    size : "M"
});

定义一个函数,没有依赖: 

define(function () {
    //TODO
    return {
        color : "black",
        size : "M"
    }
});

定义一个有依赖的函数,第一个参数是依赖的模块ID数组,后面是回调函数,会在所有依赖加载完毕后执行: 

define(["cart"], function (cart) {
    //TODO
    return {
        color : "blue",
        size : "M",
        addToCart : function () {
            cart.add(this);
        }
    }
});

当然不一定只是返回Object,也可以返回一个函数: 

define(["cart"], function (cart) {
    //TODO
    return function (title) {
        return title ? (window.title = title) : cart.name;
    }
});

更多的API可以参考官方说明。 

RequireJS 工作原理

RequireJS 采用 head.appendChild() 的方式来加载所有依赖的脚本,这个方式的原理很简单,看看下面的代码就明白了:

function loadjscssfile(filename, filetype) {
    if (filetype == "js") { //作为js文件载入
        var fileref = document.createElement('script')
        fileref.setAttribute("type", "text/javascript")
        fileref.setAttribute("src", filename)
    }
    else if (filetype == "css") {  //作为css文件载入
        var fileref = document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("type", "text/css")
        fileref.setAttribute("href", filename)
    }
    if (typeof fileref != "undefined")
        document.getElementsByTagName("head")[0].appendChild(fileref)
}
loadjscssfile("myscript.js", "js")
loadjscssfile("javascript.php", "js")
loadjscssfile("mystyle.css", "css")

RequireJS 会顺着依赖链(也就是顺着模块声明的依赖层层进入,直到没有依赖为止)把所有需要加载的模块按顺序一一加载完毕,然后才执行回调函数。

加载非规范的模块

在加载没有实现AMD规范的模块(这种模块比实现了AMD规范的模块更多)时,RequireJS 也提供了简洁的方式,就是通过配置定义这些模块的特征,比如:

requirejs.config({
    // 要使用 shim 来配置没有实现 AMD 规范的模块
    // 不过注意 shim 不能用来配置已经实现 AMD 规范的模块
    shim : {
        'backbone' : {
            //定义依赖,会在 backbone.js 载入前载入这些依赖
            deps : ['underscore', 'jquery'],
            //导出 Backbone
            exports : 'Backbone'
        },
        'underscore' : {
            exports : '_'
        }
    }
});
//jQuery
requirejs.config({
    shim : {
        'jquery.colorize' : {
            deps : ['jquery'],
            exports : 'jQuery.fn.colorize'
        },
        'jquery.scroll' : {
            deps : ['jquery'],
            exports : 'jQuery.fn.scroll'
        }
    }
});

 

 

 

 

 

  • 大小: 3.7 KB
分享到:
评论

相关推荐

    理解javascript模块化_.docx

    JavaScript模块化是编程实践中一种重要的组织代码的方式,它使得代码可重用性增强,提高了开发效率,降低了维护难度。本文将深入探讨JavaScript模块化的概念、方法以及如何实现小而简洁的模块。 首先,模块化的基本...

    基于RequireJS和JQuery的模块化编程——常见问题全面解析

    RequireJS和JQuery是两种在前端开发中常用的技术,它们可以帮助开发者更高效地进行模块化编程。RequireJS是一个支持AMD(异步模块定义)规范的JavaScript模块加载器,能够解决JavaScript在浏览器端的依赖和加载问题...

    OYE AMD模块化开发部署实践 共18页.ppt

    **模块化开发的意义** 在现代Web开发中,随着网站向Web应用程序的转变,代码量逐渐增加,复杂性也随之提升。为了有效地管理和维护这些代码,模块化开发变得至关重要。模块化可以将大型项目拆分为可重用、独立的组件...

    RequireJS-源码.rar

    总的来说,RequireJS通过AMD规范实现了JavaScript模块化,解决了异步加载和依赖管理的问题,提升了前端开发的效率和代码质量。深入研究其源码,有助于我们更好地利用这一工具,创建高效、可维护的前端项目。

    狂神说——大前端进阶NodeJS、Npm、Es6、Babel、Webpack、模块化使用笔记

    综上所述,"狂神说——大前端进阶NodeJS、Npm、Es6、Babel、Webpack、模块化使用笔记"这个主题涵盖了现代前端开发的重要技术栈。Node.js作为后端基础,Npm辅助管理依赖,ES6提供了更优雅的语法,Babel确保了新特性的...

    在JavaScript应用中使用RequireJS来实现延迟加载

    总之,在JavaScript应用中,尤其是在开发大型应用时,使用RequireJS来实现延迟加载和模块化管理,是提升性能和维护性的有效手段。它通过模块化来优化代码结构,通过依赖管理减少不必要的代码加载,最终实现应用的...

    主要解决使用requireJs开发所带来的请求次数多的问题

    RequireJS允许开发者按需加载JavaScript模块,提高了代码的可维护性和组织性。然而,随着项目规模的增长,引入的模块数量增多,这可能导致网络请求次数过多,从而影响页面加载速度和用户体验。这就是标题中所提到的...

    基于RequireJS和JQuery的模块化编程日常问题解析

    RequireJS 和 SeaJS 是两种常用的 JavaScript 模块化加载框架,它们都遵循着各自的模块定义标准——AMD(Asynchronous Module Definition)和 CMD(Common Module Definition)。 **AMD** 的代表是 RequireJS,它的...

    requireJS-test:一个简单的学习requireJS的测试站点

    RequireJS 是一个 JavaScript 库,主要用于模块化管理和加载 JavaScript 文件。在前端开发中,随着项目的复杂度增加,JavaScript 文件的数量也会随之增多,手动管理这些文件的依赖关系会变得非常困难。RequireJS ...

    modular-pkg-1:模块化家庭套餐

    **模块化家庭套餐——AngularAMD与RequireJS的深度解析** 在现代Web开发中,模块化已经成为了一种不可或缺的编程范式。"modular-pkg-1:模块化家庭套餐" 提供了一个集成AngularAMD和RequireJS的解决方案,帮助开发者...

    exemplo-buildAMD:使用 RequireJS 构建以 AMD 标准编写的 javascript 模块 - 异步模块定义

    总之,"exemplo-buildAMD"是一个关于使用RequireJS和AMD的实战示例,对于提升JavaScript模块化编程能力,特别是对异步加载和依赖管理的理解,有着重要的学习价值。通过研究这个项目,开发者不仅可以掌握AMD模式,还...

    Java Script 经典教程(六)——JavaScript语言教程

    CommonJS(Node.js环境)和AMD(RequireJS)是另外两种常见的模块化解决方案。 错误处理: JavaScript通过`try...catch`块来捕获和处理运行时错误。`throw`语句用于抛出自定义错误,而`finally`块确保无论是否发生...

    Herman, 2013, Effective JavaScript

    - **模块化开发:** - 学习如何将大型程序分解成小的、易于管理的模块,并了解不同模块化方案(如CommonJS、AMD)之间的差异。 - 使用模块加载器(如RequireJS)来优化加载过程。 - **代码风格与规范:** - 遵循...

    javaScript权威指南(附源码)

    在ES6之前,JavaScript没有内置的模块系统,但可以通过CommonJS(Node.js)或AMD(RequireJS)实现模块化。ES6 引入了import和export关键字,使得在浏览器和Node.js中都能进行原生的模块化编程。 九、DOM操作 ...

    javaScript语句大全2015

    总的来说,2015年的JavaScript语句大全涵盖了变量声明、控制流程、函数、数据结构、面向对象、错误处理、异步编程和模块化等多个方面。这些知识点构成了JavaScript编程的基础,对于任何想要深入了解和使用JavaScript...

    avalon+require前端框架DEMO

    在大型项目中,require.js能够帮助我们组织代码,实现模块化开发,避免全局变量污染,提升代码的可读性和可复用性。通过AMD(Asynchronous Module Definition)规范,require.js支持异步加载依赖,使得页面可以按需...

    JavaScript模块规范之AMD规范和CMD规范

    目前,随着ES6的出现,JavaScript模块化有了新的标准——ES6模块化标准。ES6模块化标准通过import和export关键字来导入和导出模块,支持静态模块结构,提供更强大的模块化特性。这使得AMD和CMD等传统的JavaScript...

    javascript视频教程

    8. **模块化**:JavaScript提供了多种模块化方案,如CommonJS(Node.js中使用)、AMD(Asynchronous Module Definition,如RequireJS)以及ES6引入的模块系统。 9. **事件处理**:在Web开发中,JavaScript通过事件...

    RequireJS:requirejs 的测试项目

    RequireJS 是一个 JavaScript 库,...虽然现在有许多新的工具和框架(如 ES6 的模块系统、Webpack、Rollup 等)已经替代了 RequireJS 的部分功能,但其核心思想——模块化和异步加载,依然是现代前端开发中的重要概念。

    Backbone.js应用程序开发

    , 《backbone.js应用程序开发》先从了解mvc、spa和backbone的基本知识开始,然后着手构建示例应用程序——一个简单的todo列表应用程序、restful风格的图书应用程序、以及使用backbone和requirejs的模块化应用程序。...

Global site tag (gtag.js) - Google Analytics