使用基于 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)
相关文章
|
监控 网络协议 Unix
不逊色Zabbix的开源监控LibreNMS:全功能网络监控
不逊色Zabbix的开源监控LibreNMS:全功能网络监控
2034 0
不逊色Zabbix的开源监控LibreNMS:全功能网络监控
|
IDE Java 开发工具
从零开始学Java Socket编程:客户端与服务器通信实战
【6月更文挑战第21天】Java Socket编程教程带你从零开始构建简单的客户端-服务器通信。安装JDK后,在命令行分别运行`SimpleServer`和`SimpleClient`。服务器监听端口,接收并回显客户端消息;客户端连接服务器,发送“Hello, Server!”并显示服务器响应。这是网络通信基础,为更复杂的网络应用打下基础。开始你的Socket编程之旅吧!
269 3
|
11月前
|
安全 搜索推荐 数据安全/隐私保护
VoceChat站内社区:连接你我,共享精彩
VoceChat站内社区提供语音和文本通讯,内置丰富主题板块,支持实时互动、群组聊天和个人化设置,保障数据安全。用户可在此分享、讨论、组织活动,结交全球好友,构建开放包容的交流空间。官方部署教程:&lt;https://doc.voce.chat/zh-cn/install/docker&gt;,推荐使用阿里云服务器部署。
314 3
|
JSON 自然语言处理 物联网
大语言模型数据增强与模型蒸馏解决方案
本方案以通义千问2(Qwen2)大语言模型为基础,为您介绍大语言模型数据增强和蒸馏解决方案的完整开发流程。
|
前端开发 JavaScript PHP
【PHP开发专栏】jQuery与PHP实现Ajax通信
【4月更文挑战第30天】本文介绍了使用jQuery和PHP实现Ajax通信的步骤。首先,讲解了Ajax的基础和jQuery简化Ajax操作的概念。接着,展示了如何使用jQuery的`$.get()`、`$.post()`和`$.ajax()`方法发送GET和POST请求,以及如何控制请求细节。在PHP端,讨论了接收和响应Ajax请求的方法,包括处理数据、设置响应类型和错误处理。结合jQuery与PHP,开发者能实现高效、无缝的异步数据传输,提升Web应用的用户体验。
294 1
|
前端开发 JavaScript Java
SpringCloudGateway网关服务实现文件上传功能
SpringCloudGateway网关服务实现文件上传功能
285 1
|
5G 网络架构
计算机网络与技术——物理层
物理层是计算机网络OSI模型中最低的一层,它规定了为传输数据所需要的物理链路的创建、维持、拆除,以及提供具有机械的、电子的、功能的和规范的特性。物理层考虑的是怎样才能在连接各种计算机的传输媒体上传输数据比特流,而不是具体的传输媒体。物理层的主要任务是为数据传输提供可靠的环境,它为设备之间的数据通信提供传输媒体及互连设备,确保原始的数据可在各种物理媒体上传输。物理层的基本概念包括物理层的作用、物理层的主要任务、数据在传输媒体上的传输方式等。用于物理层的协议也常称为物理层规程(procedure),其实物理层规程就是物理层协议。
计算机网络与技术——物理层
|
存储 边缘计算 人工智能
【边缘计算与AI】分析边缘计算在处理AI任务、优化响应速度和数据隐私保护方面的作用和潜力
边缘计算与AI的结合是当前技术发展的重要趋势,两者相互依存、相互促进,共同推动着数字化转型的深入发展。以下是对边缘计算与AI关系的详细分析
473 6
|
安全 API 开发工具
开发api数据接口的工作步骤
本文概述了使用Python的Flask框架开发简单API数据接口的基本步骤。首先,需明确API提供的数据及其来源,确保数据的真实可靠。其次,选择合适的开发工具和技术栈,如Python结合Flask,并安装所需环境。编写代码时,应导入必要模块、创建应用实例、定义数据、设计路由及处理函数,并考虑错误处理和日志记录。测试阶段,在本地启动服务器并使用工具验证功能和性能。最后,选择合适平台部署API,并确保其稳定性和安全性。在整个过程中,需注重数据安全、代码质量及系统性能优化。
|
SQL NoSQL 数据库
深入浅出:微服务架构下的数据库事务管理
【2月更文挑战第12天】 在当今微服务架构日益流行的背景下,如何有效地管理跨服务的数据库事务成为了开发与维护中的一大挑战。本文旨在探讨微服务环境下数据库事务管理的关键技术和策略,包括但不限于分布式事务的基本概念、常见的解决方案(如两阶段提交、补偿事务等),以及这些方案在实际应用中的优缺点比较。通过深入浅出的方式,本文希望能够帮助读者更好地理解并应对微服务架构下的数据库事务管理问题,进而提升系统的稳定性和可靠性。
304 4