前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >requireJS

requireJS

作者头像
奋飛
发布2019-08-15 10:17:23
1.7K0
发布2019-08-15 10:17:23
举报
文章被收录于专栏:Super 前端

requireJS(http://www.requirejs.cn/)是一个JavaScript模块加载器。它非常适合在浏览器中使用,使用RequireJS加载模块化脚本将提高代码的加载速度和质量。

一、CommonJS和AMD

在介绍requireJS之前,要先说一下模块规范。目前,通行的Javascript模块规范共有两种:CommonJS和AMD。

1. node.js的模块系统,就是参照CommonJS规范实现的。

代码语言:javascript
复制
var math = require('math');	//加载指定模块
math.add(2,3);

2. 浏览器环境

由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。

代码语言:javascript
复制
var math = require('math');	//加载指定模块
math.add(2,3);

第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。

这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。 因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

3. AMD

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

代码语言:javascript
复制
require(['math'], function (math) {
	math.add(2, 3);
});

目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js。

二、为什么使用requireJS

传统依次加载多个js文件。

代码语言:javascript
复制
<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>

缺点: (1)加载时,浏览器会停止网页渲染;加载文件越多,网页失去响应的时间就会越长。 (2)js文件之间存在依赖关系,必须严格保证加载顺序。而且脚本的加载是同步的。 解决方案: (1)可以使用async和defer关键字使得加载异步,但可能因此在加载过程中丢失加载的顺序。

代码语言:javascript
复制
<script src="jsFile.js" async="true"></script>
<script src="jsFile.js" defer></script>

(2)另一个选择是将所有的脚本捆绑打包在一起,但在捆绑的时候你仍然需要把它们按照正确的顺序排序。 (3)requireJS

  • 实现js文件的异步加载,避免网页失去响应;
  • 管理模块之间的依赖性,便于代码的编写和维护。
  • 代码以模块化的方式组织,可以实现按需、并行、延时载入js库。

三、requireJS实现机制

RequireJS使用head.appendChild()将每一个依赖加载为一个script标签。 RequireJS等待所有的依赖加载完毕,计算出模块定义函数正确调用顺序,然后依次调用它们。 在同步加载的服务端JavaScript环境中,可简单地重定义require.load()来使用RequireJS。

四、requireJS的加载

代码语言:javascript
复制
<pre name="code" class="html"><script src="js/require.js"></script>
代码语言:javascript
复制
代码语言:javascript
复制

载这个文件,也可能造成网页失去响应,解决方法:一放到网页底部加载;二异步加载

代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
<script src="js/require.js" defer async="true"></script>

1. 主模块:data-main

require.js在加载的时候会检察data-main属性。data-main属性的作用是,指定网页程序的主模块。由于requireJS默认的文件后缀名是js,所以可以把main.js简写成main。

代码语言:javascript
复制
<script src="js/require.js" data-main="js/main"></script>
/* main.js */
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
	// some code here
});

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

2. 模块配置

使用require.config()方法,我们可以对模块的加载行为进行自定义。可以放到require.config.js文件中,但此js必须在require.js加载后再进行加载!

代码语言:javascript
复制
<script data-main="./js/main.js" src="./js/libs/require.js" ></script>
<script src="./js/require.config.js"></script>
代码语言:javascript
复制
require.config({
	// 所有模块的查找根路径
	baseUrl: "js/lib",
	// paths指定各个模块的加载路径
	paths: {
		"jquery": "jquery.min",
		"underscore": "underscore.min",
		"backbone": "backbone.min"
	}
});

3. 定义模块:避免全局名称空间污染

require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。

代码语言:javascript
复制
/* math.js */
define(function (){
	var add = function (x,y){
    return x+y;
	};
	return {
		add: add
	};
});
/* main.js 加载方法 */
require(['math'], function (math){
	console.log(math.add(1,2));
});

4. 加载非规范的模块:shim

理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合,比如underscore和backbone这两个库。

代码语言:javascript
复制
require.config({
	shim: {
		'underscore':{
			// exports值(输出的变量名),表明这个模块外部调用时的名称
			exports: '_'
		},
    'backbone': {
			// deps数组,表明该模块的依赖
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    }
  }
});

5. map: 对于给定的模块前缀,使用一个不同的模块ID来加载该模块。

代码语言:javascript
复制
requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.1'
        },
        '*': {
        	'foo': 'foo1.0'
        }
    }
});

foo1.0.js foo1.1.js foo1.2.js some/newmodule.js some/oldmodule.js some/module.js

当“some/newmodule”调用了“require('foo')”,它将获取到foo1.2.js文件; 当“some/oldmodule”调用了“require('foo')”,它将获取到foo1.1.js; 当其他调用了“require('foo')”,它将获取到foo1.0.js

6. requireJS插件

(1)domready插件,可以让回调函数在页面DOM结构加载完成后再运行。

代码语言:javascript
复制
require(['domready!'], function (doc){
	// called once the DOM is ready
});

(2)text和image插件,则是允许require.js加载文本和图片文件。

代码语言:javascript
复制
define([
    'text!review.txt',
    'image!cat.jpg'
  ],
  function(review,cat){
    console.log(review);
    document.body.appendChild(cat);
}
);

(3)json和mdown插件,用于加载json文件和markdown文件。 注意: (1)RequireJS使用head.appendChild()将每一个依赖加载为一个script标签。 (2)RequireJS等待所有的依赖加载完毕,计算出模块定义函数正确调用顺序,然后依次调用它们。 (3)在同步加载的服务端JavaScript环境中,可简单地重定义require.load()来使用RequireJS。 (4)require.js要求,每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年07月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、CommonJS和AMD
    • 1. node.js的模块系统,就是参照CommonJS规范实现的。
      • 2. 浏览器环境
        • 3. AMD
        • 二、为什么使用requireJS
        • 三、requireJS实现机制
        • 四、requireJS的加载
          • 1. 主模块:data-main
            • 2. 模块配置
              • 3. 定义模块:避免全局名称空间污染
                • 4. 加载非规范的模块:shim
                  • 5. map: 对于给定的模块前缀,使用一个不同的模块ID来加载该模块。
                    • 6. requireJS插件
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档