使用基于 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)
相关文章
|
3月前
|
JavaScript 前端开发 开发工具
深入了解 AMD 和 CMD 规范:探索模块加载的世界(下)
深入了解 AMD 和 CMD 规范:探索模块加载的世界(下)
|
9月前
|
缓存 JavaScript 前端开发
require与vue相结合的AMD开发模式
最近开发了一个单页面应用,但不是基于vue-cli开发。 项目整体使用ES5开发,采用将require与vue相结合的AMD开发模式。
121 0
|
8月前
|
JavaScript 前端开发
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
72 0
|
8月前
|
缓存 JavaScript API
【AMD、CMD和CommonJS】
【AMD、CMD和CommonJS】
46 0
|
9月前
|
设计模式 前端开发 JavaScript
CJS,AMD,UMD和ESM区别
说到 CJS, AMD, UMD 和 ESM 四者的区别,不得不提一下模块这个概念。 CJS CJS(CommonJs) 适用于后端 Node。 Node 与 Javascript 最开始是没有模块这
231 0
|
9月前
|
Web App开发 前端开发 JavaScript
UMD 被淘汰了吗?不考虑的 UMD 的库如何在纯 UMD 前端项目中运行?
UMD 被淘汰了吗?不考虑的 UMD 的库如何在纯 UMD 前端项目中运行?
134 0
|
JavaScript 前端开发
js 模块化基础和模块规范AMD、CMD、ES6模块
js 模块化基础和模块规范AMD、CMD、ES6模块
88 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)
本篇文章介绍了前端模块化的发展过程,以及常用的模块化规范。
678 1
|
JavaScript 前端开发 Java
服从AMD规范的require.js库的学习
服从AMD规范的require.js库的学习
116 0