三、了解前端模块化系列(3)——模块化规范-AMD

121 阅读4分钟

了解前端模块化系列内容:
三、了解前端模块化系列(1)——模块化的理解
三、了解前端模块化系列(2)——模块化规范-CommonJS
三、了解前端模块化系列(3)——模块化规范-AMD
三、了解前端模块化系列(4)——模块化规范-CMD & ES6
三、了解前端模块化系列(5)——模块化规范-UMD & 总结(CommonJS AMD CMD ES6 UMD)

三、模块化规范

3.2 AMD(Asynchronous Module Definition)

3.2.1 概念

规范加载模块方式含义例子时间
CommonJS 规范同步加载模块加载完成,执行后面服务器编程 Node.js,本地硬盘已存在模块文件,加载块,不考虑非同步加载方式,适用 CommonJS
AMD 规范非同步加载模块允许指定回调函数浏览器环境,从服务器端加载模块,非同步模式,浏览器端一般 AMD 规范AMD 规范早于 CommonJS 在浏览器端实现

3.2.2 基本语法

  1. 定义暴露模块(无依赖/有依赖):

    //定义没有依赖的模块
    define(function () {
      return 模块
    })
    
    //定义有依赖的模块
    define(['module1', 'module2'], function (m1, m2) {
      return 模块
    })
    
  2. 引入使用模块:

    require(['module1', 'module2'], function (m1, m2) {
      使用m1 / m2
    })
    

3.2.3 AMD 实现(AMD 实际使用效果)

1.未使用 AMD 规范(未使用 require.js)

缺点:

  • 发送多个请求
  • 按顺序引入 js,否则报错。

dataService.js

;(function (window) {
  // 【IIFE模式】【1.作用】——①数据私有
  let msg = 'www.xianzao.com'
  // 【IIFE模式】【2.编码】——①函数内部封装:**数据**&行为
  function getMsg() {
    return msg.toUpperCase()
  }
  // 【IIFE模式】【2.编码】——②window添加属性,向外暴露接口
  window.dataService = { getMsg }
})(window) // 【IIFE模式】【3.bug】——当前模块依赖另一个模块,怎么办?

alerter.js

;(function (window, dataService) {
  // 【IIFE模式】【1.作用】——①数据私有
  let name = 'xianzao'
  // 【IIFE模式】【2.编码】——①函数内部封装:**数据**&行为
  function showMsg() {
    // 【IIFE模式】【1.作用】——②外部只能通过暴露方法操作
    alert(dataService.getMsg() + ', ' + name)
  }
  // 【IIFE模式】【2.编码】——②window添加属性,向外暴露接口
  window.alerter = { showMsg }
})(window, dataService) // 【IIFE模式增强】库当作参数传入

main.js

;(function (alerter) {
  // 【IIFE模式】【1.作用】——②外部只能通过暴露方法操作
  alerter.showMsg()
})(alerter) // 【IIFE模式增强】库当作参数传入

index.html

  • 注意:按顺序引入 dataService.js,alerter.js,main.js
<div><h1>1.未使用 AMD 规范(未使用 require.js)</h1></div>
<p>注意:按顺序引入 dataService.js,alerter.js,main.js</p>
<script type="text/javascript" src="js/modules/dataService.js"></script>
<script type="text/javascript" src="js/modules/alerter.js"></script>
<script type="text/javascript" src="js/main.js"></script>

弹框展示,输出结果:

WWW.XIANZAO.COM, xianzao
2.使用 AMD 规范(使用 require.js)

RequireJS 工具库:

  • 管理客户端模块
  • 遵循 AMD 规范

RequireJS 基本思想:

  • define 定义模块
  • require 加载模块

AMD 规范(RequireJS)在浏览器实现的步骤:

  1. 下载 require.js-V2.3.6 & require.min.js-V2.3.6 ,并引入。

  2. 创建项目结构

    |-js
      |-libs
        |-jquery
          |-2.0.0
            |-jquery.min.js
        |-requirejs
          |-2.3.6
            |-require.js
            |-require.min.js
      |-modules
        |-alerter.js
        |-dataService.js
      |-main.js
    |-index.html
    
  3. 定义 modules 目录下的模块代码

    js/modules/dataService.js

    // dataService.js文件
    // 定义没有依赖的模块
    define(function () {
      let msg = 'www.djsz3y.xyz'
      function getMsg() {
        return msg.toUpperCase()
      }
      return { getMsg } // 暴露模块
    })
    

    js/modules/alerter.js

    • 没引入第三方模块前——alerter.js
    //alerter.js文件
    // 定义有依赖的模块
    define(['dataService'], function (dataService) {
      // define(["dataService", "jquery"], function (dataService, $) {
      let name = 'djsz3y'
      function showMsg() {
        alert(dataService.getMsg() + ', ' + name)
      }
      // $("body").css("background", "yellowgreen");
      // 暴露模块
      return { showMsg }
    })
    

    js/main.js

    • 没引入第三方模块前——main.js
    // main.js文件
    ;(function () {
      require.config({
        baseUrl: 'js/', //基本路径 出发点在根目录下
        paths: {
          // 自定义模块——映射: 模块标识名: 路径
          alerter: './modules/alerter', //此处不能写成alerter.js,会报错
          dataService: './modules/dataService'
          // // 第三方库模块
          // jquery: "./libs/jquery/2.0.0/jquery.min", //注意:写成jQuery会报错
        }
      })
      require(['alerter'], function (alerter) {
        alerter.showMsg()
      })
    })()
    

    index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Modular Demo(AMD-RequireJS)</title>
      </head>
      <body>
        <!-- 引入require.js并指定js主文件的入口 -->
        <script
          data-main="js/main"
          src="js/libs/requirejs/2.3.6/require.js"
        ></script>
      </body>
    </html>
    
  4. 引入第三方库:

    在 alerter.js 文件中引入 jQuery 第三方库,main.js 文件也要有相应的路径配置。

    1. 修改 alerter.js

      修改:js/modules/alerter.js

      // alerter.js文件
      // 定义有依赖的模块
      define(['dataService', 'jquery'], function (dataService, $) {
        // ...
        // ...
        $('body').css('background', 'yellowgreen')
        // ...
      })
      
    2. 修改 main.js

      添加两行

      • 一行注释,

      • 一行映射 jquery

      修改:js/main.js

      // main.js文件
      ;(function () {
        require.config({
          baseUrl: 'js/', //基本路径 出发点在根目录下
          paths: {
            // 自定义模块——映射: 模块标识名: 路径
            alerter: './modules/alerter', //此处不能写成alerter.js,会报错
            dataService: './modules/dataService',
      ++++++// 第三方库模块
      ++++++jquery: './libs/jquery/2.0.0/jquery.min' //注意:写成jQuery会报错
          }
        })
        require(['alerter'], function (alerter) {
          alerter.showMsg()
        })
      })()
      
  5. 效果:

    • 未引入第三方模块
      1. 弹框展示结果:WWW.DJSZ3Y.XYZ, djsz3y
    • 引入第三方模块
      1. 弹框展示结果:WWW.DJSZ3Y.XYZ, djsz3y
      2. 并且 body 背景变为黄绿色。
  6. 测试:

    • 确实 js/main.jsalerter & dataService 模块引入顺序不分先后
    • 很快

3.2.4 总结

AMD 规范:

  1. 定义方法清晰不污染全局环境,依赖关系清楚
  2. 可用于浏览器环境
    非同步、按需动态加载模块。

3.2.5 可供参考链接

requirejs 官网-start.html#get

requirejs 官网-download

requireJS 的基本用法

友情链接