Require.js 基本用法详解:异步加载与模块依赖管理

作者:异步漫步时间:2026-10-22 05:25:48浏览:244

本文详解 Require.js 的核心用法,涵盖其作为 AMD 规范实现者如何解决 JS 阻塞渲染与依赖排序问题。内容包含引入配置、define 与 require API 使用、路径映射及非 AMD 模块的 shim 兼容处理,帮助开发者实现高效的模块化前端开发。

Require.js 概述

一、什么是 Require.js

①:Require.js 是一个遵循 AMD(Asynchronous Module Definition,异步模块定义)规范的 JavaScript 脚本加载器。它实现了脚本的异步加载,确保不会阻塞页面渲染或后续脚本的执行,并在加载完成后提供执行回调函数的功能;

②:Require.js 强制要求 JavaScript 脚本必须实现模块化,即文件化。其核心作用之一就是加载这些 JS 模块(JS 文件)。

③:Require.js 能够管理 JS 模块或文件之间的依赖关系。例如,jQuery、AngularJS 等不同框架采用不同的语法,且依赖这些语法的 JS 文件必须在 jQuery.js 或 Angular.js 之后导入才能正常执行,而 Require.js 可以解决这种排序依赖问题。

使用 Require.js 的原因

二、为什么要使用 Require.js

①:在加载过程中,浏览器会停止网页渲染,原因如下:

在不使用 Require.js 的情况下,文件编写方式通常如下:


<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="a.js"></script>
  </head>
  <body>
   <span>Hellow World</span>
  </body>
</html>

在导入的 a.js 文件中:


(function(){
  function fun1(){
   alert("JS文件已生效");
  }
  fun1();
})()

运行上述代码时,我们可以观察到在 alert 弹出提示框出现时,网页 HTML 部分仍然是空白的,未显示任何内容。只有点击“确定”后,“Hellow World”才会显示在网页中,这是 JS 阻塞浏览器渲染导致的结果。加载的文件越多,网页失去响应的时间就越长。

②:由于 JS 文件之间存在依赖关系,因此必须严格保证加载顺序,依赖性最大的模块一定要放到最后加载。当依赖关系复杂时,代码的编写和维护都会变得困难。例如:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script type="text/javascript" src="js/jquery-1.10.2.js" ></script>
    <script type="text/javascript" src="js/b.js" ></script>
  </head>
  <body>
    <div id="div1" style="width: 100px;height: 100px;background-color: red;"></div>
  </body>
</html>

在 b.js 文件中


$(function(){
  $("#div1").css("background-color","blue");
})

为了使 b.js 中的代码生效,必须将 <script type="text/javascript" src="js/b.js"></script> 这行代码放在 <script type="text/javascript" src="js/jquery-1.10.2.js"></script> 后面。这样,当使用的框架和 JS 文件较多时,它们的导入顺序就会变得非常繁琐。

Require.js 的诞生正是为了解决上述两个问题:

1. 实现 JS 文件的异步加载,避免网页失去响应;

2. 管理模块之间的依赖性,便于代码的编写和维护。

Require.js 的引入与配置

三、Require.js 的加载

①:首先,我们需要去官网下载最新版本,官方网址:http://requirejs.org/docs/download.html

下载完成后,将其放在网站项目的 js 子文件夹下即可使用:


<script src="js/require.js"></script>

这里可能会遇到一个问题:加载这个文件也可能造成网页失去响应,解决该问题有两种方法:

1. 将这行代码写成如下格式:


<script src="js/require.js" defer async="true" ></script>

其中,async 属性和 defer 属性表明该文件需要异步加载,从而避免网页失去响应。IE 仅支持 defer 属性,不支持 async 属性。

2. 将文件放到网页底部加载。

②:加载完 Require.js 之后,我们就可以加载自己的代码了。假设我们的 JS 文件命名为 main.js,同样置于 js 文件夹下,那么只需执行如下代码:


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

上述代码中,data-main 属性的作用是指定网页程序的主模块,即 js 目录下的 main.js。该文件会第一个被 Require.js 加载。由于 Require.js 默认的文件后缀名为 js,因此可以省略 ".js" 简写为 main。

核心 API:define 与 require

四、基本 API

在上一部分中,我们引入了 main.js 文件,main.js 的写法如下:


define(function(){
  function fun1(){
   alert("main.js已生效");
  }
  fun1();
})

这样,我们就通过 define 函数定义了一个模块,然后在页面中通过 AMD 规范定义的 require() 函数使用:


require(["js/main"]);

一般情况下,它会依赖于其他 JS 框架,比如 jQuery 等。此时,我们需要在页面文件中按照以下格式来写:


require(['A', 'B', 'C'], function (A, B, C){
  // js代码
});

require() 函数接受两个参数。第一个参数是一个数组,表示所依赖的框架,上例即为 ['A', 'B', 'C'],意味着 main.js 中的代码需要用到这三个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

require() 会异步加载 A、B、C 三个模块,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,从而解决了依赖性的问题。

下面,我们就以 jQuery 为例,说明这个函数是如何运行的:


require(['jquery'], function ($){
  // jquery代码
});

Require.js 会先加载 jQuery,然后再运行回调函数。main.js 的代码就写在回调函数中。注意:require 中的依赖是一个数组,即使只有一个依赖,你也必须使用数组来定义。

模块路径与加载配置

五、加载文件

在上一部分中,main.js 的依赖模块是 ['jquery']。默认情况下,Require.js 会假定该模块与 main.js 在同一个目录,文件名是 jquery.js,然后自动加载。除此之外,我们可以通过 require.config() 方法对模块的加载行为进行自定义,require.config() 就写在 main.js 的头部,它的参数是一个对象,该对象的 paths 属性指定各个模块的加载路径。


require.config({
    paths: {
      "jquery": "jquery.min",
      "anjular": "anjular.min"
    }
  });

上述模块路径默认与 main.js 在同一个目录(js 子目录)。如果这些模块在其他目录,比如 js/lib 目录,则有两种写法。一种是逐一指定路径:


require.config({
    paths: {
      "jquery": "lib/jquery.min",
      "anjular": "lib/anjular.min"
    }
  });

另一种则是直接改变根目录(baseUrl):


require.config({
    baseUrl: "js/lib",
    paths: {
      "jquery": "jquery.min",
      "anjular": "anjular.min"
    }
  });

之前的例子中加载模块都是本地 JS,但大部分情况下网页需要加载的 JS 可能来自本地服务器、其他网站或 CDN,这样就不能通过这种方式来加载了。我们以加载一个 jQuery 库为例:


require.config({
  paths : {
    "jquery" : ["http://libs.baidu.com/jquery/2.0.3/jquery"] 
  }
})

上面的例子中重复出现了 require.config 配置,如果每个页面中都加入配置,必然会十分麻烦。Require.js 提供了一种叫“主数据”的功能,我们可以将所有的 require.config 配置放到 main.js 中,在页面中调用它:


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

就可以使每一个页面都使用这个配置,然后页面中就可以直接使用 require 来加载所有的短模块名。

AMD 模块定义规范

六、AMD 模块的写法

Require.js 加载的模块采用 AMD 规范,也就是说,模块必须按照 AMD 的规定来写。具体来说,就是模块必须采用特定的 define() 函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在 define() 函数之中。假定现在有一个 math.js 文件,它定义了一个 math 模块。那么,math.js 就要这样写:


define(function (){
    var add = function (x,y){
      return x+y;
    };
    return {
      add: add
    };
  });

然后在页面中:


require(['math'], function (math){
  alert(math.add(1,1));
});

如果这个 JS 文件还依赖其他模块,那么 define() 函数的第一个参数必须是一个数组,指明该模块的依赖性。


define(['jquery'], function($){
  $("#div1").css("background-color","red");
})
 

当 require() 函数加载上面这个模块的时候,就会先加载 jquery.js 文件。

处理非 AMD 模块:Shim 配置

七、第三方模块

通过 Require 加载的模块一般都需要符合 AMD 规范,即使用 define 来申明模块。但是部分时候需要加载非 AMD 规范的 JS,这时候就需要用到另一个功能:shim:

1. 非 AMD 模块输出,将非标准的 AMD 模块变成可用的模块。例如:在老版本的 jQuery 中,是没有继承 AMD 规范的,所以不能直接 require["jquery"],这时候就需要 shim:


require.config({
  shim: {
    "jquery" : {exports : "$"}
  }
})

这样配置后,我们就可以在其他模块中引用 jQuery 模块:


require(["jquery"], function(_){
  $("#div1").css("background-color","red");
})

2. 插件形式的非 AMD 模块,我们经常会用到 jQuery 插件,而且这些插件基本都不符合 AMD 规范,比如 jquery.form 插件。这时候就需要将 form 插件加入到 jQuery 中:


require.config({
  shim: {
    "jquery.form" : {
      deps : ["jquery"]
    }
  }
})  
require.config(["jquery", "jquery.form"], function($){
  $(function(){
    $("#form").ajaxSubmit({...});
  })
})

以上就是 Require 的基本用法详解。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!

作者最新文章