JS | CommonJS、AMD、CMD、ES6-Module、UMD五种JS模块化规范

news2024/11/27 10:42:28

目录

前言

一、CommonJS 模块化规范

二、ES6 模块化规范

三、AMD 模块化规范

四、CMD 模块化规范

五、UMD模块化规范


前言

这三个规范都是为Js模块化加载而生的,使模块能够按需加载,使系统同庞杂的代码得到组织和管理。模块化的管理代码使多人开发得到了更好的合作。

一、CommonJS 模块化规范

是一种为JS的表现指定的规范,它希望js可以运行在任何地方,更多的说的是服务端模块规范,Node.js采用了这个规范。

CommonJS主要用于服务器端,‌Node.js是其主要实践者。

核心思想

一个单独文件就是一个模块,通过require方法来同步加载要依赖的模块,然后通过extports或者module.exports来导出需要暴露的接口。

require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;

(1) 每一个文件都是一个模块,每一个模块都有一个独立的作用域,文件内的变量,函数都是私有的,其他文件不可使用(除非赋值到 global上)

(2)每个模块内部,module变量代表当前模块

(3)每个文件对外的接口是 module.exports 属性

(4) require用于引用其他模块,实际获得的是其他模块的module.exports这个属性 

优点:服务器端模块重用,NPM中模块包多,有将近20万个。

缺点:加载模块是同步的,只有加载完成后才能执行后面的操作,也就是当要用到该模块了,现加载现用,不仅加载速度慢,而且还会导致性能、可用性、调试和跨域访问等问题。Node.js主要用于服务器编程,加载的模块文件一般都存在本地硬盘,加载起来比较快,不用考虑异步加载的方式,因此,CommonJS规范比较适用。然而,这并不适合在浏览器环境,同步意味着阻塞加载,浏览器资源是异步加载的,因此,有了AMD CMD解决方案。

实现:服务器端的 Node.js;Browserify,浏览器端的 CommonJS 实现,可以使用 NPM 的模块,但是编译打包后的 文件体积可能很大;modules-webmake,类似Browserify,还不如 Browserify 灵活;wreq,Browserify 的前身;

小结:commonjs模块化规范

CommonJS规范是同步加载模块,也就是说,在执行到require调用的时候,会立即加载并执行模块。这种同步的方式对服务器端不存在问题,因为所有的模块都在本地,可以直接加载。但是对于浏览器端,模块可能需要通过网络加载,这就需要异步加载,因此,在浏览器端,AMD和CMD规范得到了广泛的应用。

以下是CommonJS规范的一个简单示例:

假设我们有两个文件,一个是math.js,另一个是main.js

math.js:

// math.js
exports.add = function(a, b) {
    return a + b;
};
 
exports.multiply = function(a, b) {
    return a * b;
};

main.js:

// main.js
var math = require('./math');
 
console.log('2 + 3 = ' + math.add(2, 3));
console.log('2 * 3 = ' + math.multiply(2, 3));

 在math.js中,我们使用exports对象来暴露模块接口,在main.js中,我们使用require函数来加载math.js模块,并使用其提供的方法。 在Node.js环境中,你可以直接运行这两个文件,因为Node.js采用了CommonJS规范。但是在浏览器环境中,你需要使用像Browserify这样的工具来将CommonJS格式的代码转换成可以在浏览器中运行的格式。

二、ES6 模块化规范

ES6中的Module规范定义了JavaScript的模块。模块功能主要由关键字exportimport实现。

ES6 模块化适用于浏览器端和服务器端,是JavaScript语言的最新版本,通过importexport语句实现模块化。

export用于定义模块对外暴露的接口,可以用来导出变量、函数、类等。

// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

import用于从其他模块导入需要的接口。 

// app.js
import { add, subtract } from './math.js';
 
console.log(add(1, 2)); // 输出3
console.log(subtract(10, 5)); // 输出5

模块可以导出单个值,也可以全部导出。

// math.js
function add(a, b) {
  return a + b;
}
function subtract(a, b) {
  return a - b;
}
export { add, subtract };
 
// app.js
import * as math from './math.js';
 
console.log(math.add(1, 2)); // 输出3
console.log(math.subtract(10, 5)); // 输出5

 默认导出(default export)只允许每个模块有一个。

// math.js
const add = (a, b) => a + b;
export default add;
 
// app.js
import math from './math.js';
 
console.log(math(1, 2)); // 输出3

以上是ES6 Module的基本使用方法。

参考:export default 和 export之间的区别-CSDN博客

三、AMD 模块化规范

鉴于浏览器的特殊情况,又出现了一个规范,这个规范呢可以实现异步加载依赖模块,并且会提前加载,那就是AMD规范。——(Asynchromous Module Definition - 异步模块定义)

AMD主要用于浏览器端,‌RequireJS是其主要实践者。通过define()require()函数实现模块化。

其核心接口是:define(id?, dependencies?, factory) ,它要在声明模块的时候指定所有的依赖 dependencies ,并且还要当做形参传到factory 中,对于依赖的模块提前执行,依赖前置。

define("module", ["dep1", "dep2"], function(d1, d2) {
  return someExportedValue;
});
require(["module", "../file"], function(module, file) { /* ...*/ });

优点:在浏览器环境中异步加载模块;并行加载多个模块;

缺点:开发成本高,代码的阅读和书写比较困难,模块定义方式的语义不顺畅;不符合通用的模块化思维方式,是一种妥协的实现;

实现:RequireJS; curl;

小结:‌AMD规范

AMD规范的定义和基本概念‌

AMD(Asynchronous Module Definition)‌是一种异步模块定义规范,主要用于浏览器端的JavaScript模块化。它是由‌RequireJS的作者‌James Burke提出的一种模块化规范,旨在解决浏览器环境中多个JavaScript文件依赖关系的问题,并实现异步加载模块。

AMD规范的基本语法

在AMD规范中,每个模块都必须通过define函数定义。define函数可以接收两个到四个参数:第一个参数是模块的名字,第二个参数是一个数组,声明模块的依赖项,第三个参数是一个函数,该函数的参数与前面的依赖项一一对应,用于定义模块的导出成员。例如:

define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
    exports.verb = function() {
        return beta.verb();
    }
});

AMD规范的使用场景和优缺点

AMD规范适合在浏览器环境中异步加载模块,可以并行加载多个模块并按需加载。RequireJS是实现AMD规范的主要工具,它解决了多个JavaScript文件依赖关系的问题,使得浏览器可以异步加载模块,从而不会阻塞页面的渲染。

优点:

  • 适合在浏览器环境中异步加载模块。
  • 可以并行加载多个模块。
  • 按需加载模块。

缺点:

  • 需要第三方库(如RequireJS)支持。
  • 模块划分细致时,文件请求频繁。

AMD规范与其他模块化规范的对比

AMD规范与CMD规范和CommonJS规范相比,主要区别在于依赖模块的执行时机和处理方式不同。AMD规范是异步加载模块,而CMD规范是按需加载模块。CommonJS规范适用于服务器端,同步加载模块。

AMD规范通过define方法定义模块,通过require方法加载模块,而CMD规范也是通过define方法定义模块,但执行时机不同。CommonJS规范通过require命令加载模块,并通过module.exportsexports对外暴露接口。 

四、CMD 模块化规范

Common Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。——(Common Module Definition - 公共模块定义)

define(function(require, exports, module) {
  var $ = require('jquery');
  var Spinning = require('./spinning');
  exports.doSomething = ...
  module.exports = ...
})

优点:依赖就近,延迟执行 可以很容易在 Node.js 中运行;

缺点:依赖 SPM 打包,模块的加载逻辑偏重;

实现:Sea.js ;coolie

小结:CMD规范(Common Module Definition)是一种模块定义规范,它明确了模块的基本书写格式和基本交互规则。‌ CMD规范专门用于浏览器端,模块的加载是异步的,只有在模块使用时才会加载执行。CMD规范整合了CommonJS
和AMD规范的特点,提供了一个简单且与Modules规范保持较大兼容性的模块化解决方案。

在CMD规范中,一个模块就是一个文件,通过define关键字来定义模块。基本的格式是define(factory);,其中define是一个全局函数,factory可以是函数、对象或字符串。当factory为函数时,它表示模块的构造方法,执行该构造方法可以得到模块向外提供的接口。factory方法在执行时,默认会传入三个参数:require、exports和module。这三个参数分别用于引入其他模块、导出模块的内容以及获取当前模块的信息。

此外,CMD规范推荐一个文件对应一个模块,因此经常使用文件名作为模块的标识。依赖就近的原则也被推荐,即在factory函数中直接写入依赖,而不是在define的参数中指定。这种做法使得代码更加直观和易于维护。

SeaJS是遵循CMD规范的代表库之一,它提供了一个轻量级的模块加载器,使得开发者能够更加方便地使用CMD规范的模块化编程。通过SeaJS,开发者可以更加轻松地实现模块的异步加载和使用,从而提高代码的加载速度和质量‌。

五、UMD模块化规范

UMD模块化规范是AMD和CommonJS的糅合)。

UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。

在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。

(function (window, factory) {
    if (typeof exports === 'object') {
     
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
     
        define(factory);
    } else {
     
        window.eventUtil = factory();
    }
})(this, function () {
    //module ...
});

总结:

JavaScript的模块化规范主要包括​ CommonJS、AMD、CMD、ES6模块化以及UMD。 ​

  • CommonJS‌:主要应用于服务器端,每个文件都被视为一个模块,通过require函数加载模块,使用module.exportsexports对象导出模块内容。这种规范适合于Node.js环境,因为它基于服务器端JavaScript的运行环境设计,简单直观,但不适合浏览器环境,因为它采用同步加载方式‌。

  • AMD (Asynchronous Module Definition)‌:由RequireJS推广,采用异步方式加载模块,支持通过指定回调函数定义依赖模块。这种方式解决了CommonJS在浏览器环境下同步加载的问题,允许模块加载不会阻塞页面的渲染‌。

  • CMD (Common Module Definition)‌:由SeaJS推广,与AMD类似,但也支持非异步加载。它的使用方式与AMD有所不同,但同样旨在解决模块依赖和异步加载的问题‌。

  • ES6模块化‌:ECMAScript 2015引入的原生模块系统,使用importexport关键字实现模块的导入和导出。ES6模块支持静态和动态导入,具有静态解析、异步加载和更好的兼容性等优点,成为现代前端开发中最流行的模块化规范‌。

  • UMD‌:是AMD和CommonJS的混合体,旨在同时支持Node.js和浏览器环境。UMD会根据运行环境自动选择使用CommonJS或AMD的模块加载方式‌。

这些模块化规范各有特点,适用于不同的使用场景。CommonJS适合服务器端开发,而ES6模块化则更适合现代前端开发,提供了更好的异步加载和兼容性。AMD和CMD规范则主要解决了浏览器环境下模块的异步加载问题。UMD则是一种折中的解决方案,旨在同时支持Node.js和浏览器环境‌。


● 参考资料 ●

AMD规范、CMD规范、CommonJS - 简书 | JavaScript的模块规范有哪些-PHP中文网

JS中的几种模块化规范(CommonJS、AMD、CMD、ES6 Module)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2227953.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c# 值类型

目录 1、c#类型2、值类型2.1 结构体2.2 枚举 1、c#类型 类型(Type)又叫数据类型(Data Type)。 A data type is a homogeneous collection of values,effectively prensented,equipped with a set of operations which manipulate…

【YApi】接口管理平台

一、简介 YApi 是一个用于前后端开发团队协作的 API 管理平台,帮助团队更加高效地进行 API 接口的设计、测试、文档管理和版本控制等工作。 YApi 主要功能: API 设计和管理:提供 API 设计和文档生成工具,使开发者能够轻松创建、…

ubuntu20.04系统安装

文章目录 前言参考1 一、准备工作1、进入BIOS,设置 UEFI/Legacy Boot选项 为UEFI2、进入BIOS界面将Secure Boot禁用3、USB启动为enable 二、单系统安装1、插入U盘,电脑正常开机后 总结 前言 装了很多次ubuntu系统,整理一篇自己的文章很费时间…

5G 现网信令参数学习(2) - SIB1

目录 1. cellSelectionInfo 1.1 q-RxLevMin 2. cellAccessRelatedInfo 3. connEstFailureControl 4. si-SchedulingInfo 4.1 schedulingInfoList 4.2 si-WindowLength 5. servingCellConfigCommon 5.1 downlinkConfigCommon 5.1.1 frequencyInfoDL 5.1.2 initialDown…

【electron8】electron实现“图片”的另存为

注:该列出的代码,都在文章内示例出 1. 另存为按钮事件: const saveAsHandler async () > {const { path, sessionId } recordInfoif(typeof message ! string) return;// 因为我的图片是加密的,所以我需要根据接口返回的路…

Unity 两篇文章熟悉所有编辑器拓展关键类 (上)

本专栏基础资源来自唐老狮和siki学院,仅作学习交流使用,不作任何商业用途,吃水不忘打井人,谨遵教诲 编辑器扩展内容实在是太多太多了(本篇就有五千字) 所以分为两个篇章而且只用一些常用api举例&#xff0c…

数据结构——基础知识补充

1.队列 1.普通队列 queue.Queue 是 Python 标准库 queue 模块中的一个类,适用于多线程环境。它实现了线程安全的 FIFO(先进先出)队列。 2.双端队列 双端队列(Deque,Double-Ended Queue)是一种具有队列和…

基于大数据的智能家居销量数据分析

作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…

AURIX Development Studio的使用入门

目录 一、在本地目录创建工作空间文件夹 二、进入AURIX编译器 1、选择之前创建的工作空间文件夹路径 2、修改外观 3、向工作空间中导入项目文件 4、将此项目转变为活跃项目 三、烧录和编译运行 四、ADS常用快捷键 初次安装好AURIX后,如何去熟悉该编译器的使用…

『大模型笔记』如何在无网路的情况下在Linux主机上安装NVIDIA Container Toolkit(nvidia-docker2)

如何在无网路的情况下在Linux主机上安装NVIDIA Container Toolkit(nvidia-docker2) 文章目录 一. 如何在无网路的情况下在Linux主机上安装NVIDIA Container Toolkit(NVIDIA-docker2)步骤 1. 确定您的硬件环境步骤2.去这里下载deb离线安装包步骤 3. 引用以下顺序安装套件步骤 4.…

论文阅读(二十九):Multi-scale Interactive Network for Salient Object Detection

文章目录 Abstract1.Introduction2.Scale VariationProposed Method3.1Network Overview3.2Aggregate Interaction Module3.3 Self-Interaction Module3.4Consistency-Enhanced Loss 4.Experiments4.1Implementation Details4.2 Comparison with State-of-the-arts4.3Ablation …

整合Mybatis-plus及最佳实践

项目引入Mybatis-plus 第一步: 引入starter依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId> </dependency>第二步: 使用MapperScan扫描mapper文件夹 SpringBootApplication Mappe…

【IC每日一题】

IC每日一题 1&#xff1a;锁存器(latch)、触发器(flip-flop)、寄存器的概念及区别1.1 概念1.2 锁存器的危害1.3 如何避免产生锁存器 2 手撕题&#xff1a;边沿检测2.1 边沿检测(上升沿、下降沿、双边沿)2.1.1 波形图2.1.2 算法步骤2.1.3 代码 2.2 序列模三检测器2.2.1 描述2.2.…

端到端自动驾驶模型SparseDrive论文阅读笔记

为了进一步的理解模型&#xff0c;方便对模型进行调试&#xff0c;对论文进行了详细的阅读&#xff0c;记录了相关的笔记&#xff0c;和论文阅读批注。 论文阅读批注连接&#xff1a; https://note.youdao.com/s/VC6mDgdZ 笔记如下图&#xff1a;

(11)(2.1.6) Hobbywing DroneCAN ESC(一)

文章目录 前言 1 连接和配置 2 参数说明 前言 具有 CAN 接口&#xff08;including these&#xff09;的业余 ESC 支持 DroneCAN&#xff0c;它允许自动驾驶仪通过 CAN 控制 ESC /电机&#xff0c;并检索单个转速、电压、电流和温度。 具有 CAN 接口&#xff08;including …

《机器学习by周志华》学习笔记-神经网络-03多层网络学习算法之误差逆传播算法

1、背景 由于多层网络的学习能力比单层感知机要强很多,想要训练多层网络的话,感知机的学习规则显然不使用,需要更强大的学习算法来进行训练。「误差逆传播」算法就是最杰出、最成功的神经网络学习算法之一。 现实世界的业务大多数以来使用该算法进行训练。 2、作用 不仅…

.NET Core WebApi第4讲:控制器、路由

一、控制器是什么&#xff1f; 1、创建一个空的API控制器&#xff1a;TestController.cs 2、里面有一个类叫TestController&#xff0c;把它叫做控制器 因为它继承了ControllerBase类&#xff0c;ControllerBase类里提供了一系列的方法&#xff0c;使得TestController这个类具…

基于Mysql、JavaScript、PHP、ajax开发的MBTI性格测试网站(前端+后端)

源码地址&#xff1a;https://download.csdn.net/download/2302_79553009/89933699 项目简介 本项目旨在构建一个基于MBTI&#xff08;迈尔斯-布里格斯性格分类指标&#xff09;理论的在线平台——“16Personalities”。该平台利用PHP、MySQL、JavaScript等技术栈开发&#xf…

【AI开源项目】FastGPT- 快速部署FastGPT以及使用知识库的两种方式!

文章目录 一、FastGPT大模型介绍1. 开发团队2. 发展史3. 基本概念 二、FastGPT与其他大模型的对比三、使用 Docker Compose 快速部署 FastGPT1、安装 Docker 和 Docker Compose&#xff08;1&#xff09;. 安装 Docker&#xff08;2&#xff09;. 安装 Docker Compose&#xff…

SpringBoot- 查看Maven依赖API文档

在 Maven 中查看某个依赖的所有 API 文档&#xff0c;最常见的方式是通过添加 Javadoc 并使用 IDE 自动集成查看&#xff0c;或者直接访问 Maven 仓库网站。以下是详细的步骤&#xff1a; 1. 使用 Maven Dependency Plugin 下载 Javadoc 可以通过 mvn dependency:resolve 命令…