使用基于 AMD 的 RequireJS 写一个花活项目

简介: 最近在研究前端模块化,大多数文章都提到了 AMD,关于 AMD 的模块标准(或者说规范)将的都很清楚,什么异步加载、保证正确顺序,对付八股很够,但是唯独没有关于 AMD 的实操工程,大多数是纸上谈

最近在研究前端模块化,大多数文章都提到了 AMD,关于 AMD 的模块标准(或者说规范)讲的都很清楚,什么异步加载、保证正确顺序,对付八股很够,但是唯独没有关于 AMD 的实操工程,大多数是纸上谈兵,所以经过我的博览群书(其实是翻垃圾桶,十个九个抄)终于找到了在 AMD 那个年代的工程和一些简单实现)

AMD

AMD(Asynchronous Module Definition) - 异步模块定义,AMD 是一个模块规范(或者说标准),它其实是 CommonJS 规范的分支,这也就是为什么很多文章里提到 CommonJS 时往往会带上 AMD

定义

使用 AMD 规范的模块要求如下

define(id?, dependencies?, factory);
  1. id 是名称
  2. dependencies 是依赖
  3. factory 是模块逻辑

以上仅为简述,完整的 AMD 介绍请参考文档

实现

规范只是理论而不是实现,像 CommonJS 规范就有很多实现,其中最出名的就是 Node.js,还有比较经典的理论和实现的例子有 Promise A+ 规范和一系列的 Promise 实现,比如浏览器的 ES6 Promise 原生实现、开源实现 kriskowal/q...,而 AMD 的实现就是在 20092 月的推出的 RequireJS

文章例子就是基于 RequireJS 的工程实现

RequireJS 的使用

RequireJS 源于 CommonJS 但后面又从其中独立出去成立了新社区,因此没有和 CommonJS 的实现 Node.js 及其生态(npm)产生太多联系,也就是说 RequireJS 的项目是不需要 Node.js 环境的

文章使用的是 require.js@2.3.6

文章实现的是通过 JS 传递颜色名称并将对应的十六进制颜色渲染到 DOM 中,其中文件结构

├── app            - 项目代码
|  ├── utils.js    - 工具模块
|  └── main.js     - 主逻辑
├── lib            - 第三方库
|  ├── draw-dom.js
|  └── require.js
├── app.js         - 入口文件(包含 require.js 的配置)
├── index.html

目录结构基于 RequireJS 官网给出的文档中的单页应用的例子(2011 年就有单页应用的说法了!)

<!-- index.html -->
<head>
  <script data-main="app.js" src="lib/require.js" async></script>
</head>
<body>
  <h1 id="app">amd-learning</h1>
</body>

入口

入口文件主要是配置 require.js 和加载入口函数

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

require(["app/main"]);
  1. baseUrl 用于指定第三方模块的位置,后期在主逻辑中可以直接通过名称调用,比如 lib 目录下的 draw-dom 模块 require(draw-dom)
  2. paths 用来指定用户自定义模块,即源代码部分

自定义模块

目录中的 utils 就是自定义模块,在主逻辑中可以根据相对路径去引用,这一点和 CommonJS 保持一致

define(function (require) {
  const drawDOM = require("draw-dom");
  const utils = require("./utils");

  drawDOM.draw("app", utils.translate("red"));
});

注意,在引用模块时必须使用 require,而 requiredefine 函数的参数传入(这是 require.js 的默认模块)

而自定义模块导出可以选择返回一个对象作为导出值

如果工厂函数返回一个值(一个对象、函数或任何 Truthy 值),那么该值应该被分配为模块的导出值

如下

// utils.js
define(function () {
  return {
    translate: function (name) {
      let color = "";
      switch (name) {
        case "red":
          color = "#FF0000";
          break;
        default:
          color = "#000000";
      }
      return color;
    },
  };
});

第三方模块

require.js 使用的模块需要在模块源码提供处下载,此处放置在 lib 目录统一管理,为了便于描述我直接手撸了一个

define("draw-dom", ["exports"], function (exports) {
  exports.draw = function (id, color) {
    document.querySelector(String("#" + id)).style.color = color;
  };
});

注意,导出可以使用 exports 模块(exportsrequire 一样都是 require.js 的默认模块)

最后例子的运行效果如下

IMG

参考资料

  1. Javascript模块化编程(三):require.js的用法 - 阮一峰的网络日志
  2. 《编程时间简史系列》JavaScript 模块化的历史进程
  3. AMD(Asynchronous Module Definition)
相关文章
|
22天前
|
JavaScript 前端开发
多种模块格式,包括 ES, CommonJS, UMD, AMD, SystemJS 和 IIFE的区别点分别是什么?
【10月更文挑战第20天】在实际应用中,选择合适的模块格式需要根据项目的需求、目标环境以及开发团队的习惯等因素来综合考虑。不同的模块格式都有其自身的优势和适用场景,合理选择可以提高代码的组织性、可维护性和性能。
27 8
|
JavaScript 前端开发
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
113 0
|
JavaScript 前端开发
说说你对JavaScript模块化方案的理解和 CommonJS、AMD、CMD、ES6 Module 分别是什么?
模块化是指将一个复杂问题,自顶向下逐层把系统划分为若干模块的过程。对于整个系统来说,这些模块可组合,分解和更换的单元。对于编程领域的模块化就是遵守固定的原则,将一个大文件拆分成多个独立且相互依赖的小模块。简单理解模块化就是在一个js文件中能够引入另一个js文件
139 0
|
缓存 JavaScript API
【AMD、CMD和CommonJS】
【AMD、CMD和CommonJS】
68 0
|
JavaScript 前端开发
模块化开发:CommonJS、AMD 和 ES6 Modules 的区别与使用方式
在前端开发中,模块化开发是一种重要的编程方法,它可以帮助我们更好地组织和管理代码,提高代码的可维护性和复用性。在JavaScript中,有多种模块化开发的标准,包括CommonJS、AMD和ES6 Modules。让我们逐一了解它们的区别和使用方式:
207 0
|
设计模式 前端开发 JavaScript
CJS,AMD,UMD和ESM区别
说到 CJS, AMD, UMD 和 ESM 四者的区别,不得不提一下模块这个概念。 CJS CJS(CommonJs) 适用于后端 Node。 Node 与 Javascript 最开始是没有模块这
343 0
|
JavaScript 前端开发 Java
继 CJS、AMD 之后又来一个 UMD,究竟是什么?有什么用?
最近研究了一下 Vue 和 React 编译出来的版本文件,我发现 Vue 提供了 CommonJS|ES Module|ES Module browser|UMD 四种格式,而 React 提供 CommonJS|UMD 两个版本,对于 CommonJS|ES Module 对应的八股可以说是很多了,而里面夹杂的 UMD 又是什么东西呢?
|
存储 缓存 前端开发
前端模块化详解(CommonJS、AMD、CMD、ES Module)
本篇文章介绍了前端模块化的发展过程,以及常用的模块化规范。
729 1
|
JavaScript 前端开发
js 模块化基础和模块规范AMD、CMD、ES6模块
js 模块化基础和模块规范AMD、CMD、ES6模块
114 0
|
JavaScript 前端开发 Java
服从AMD规范的require.js库的学习
服从AMD规范的require.js库的学习
143 0