说说你对模块化的理解(CommonJS、AMD、CMD、ES Module)

2023-05-16

模块化的开发方式可以提高代码复用率,方便进行代码的管理。通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。目前流行的js模块规范有common js、AMD、CMD、ES Module规范

Commonjs

Node.js是Commonjs规范的主要实践者,它有四个重要的环境变量为模块化的实现提供支持:module、exports、require、global。实际使用时,用module.exports定义当前模块对外输出的接口(不推荐直接用exports),用require加载模块

// 定义模块math.js
const basicNum = 0;
function add(a, b) {
  return a + b;
}
module.exports = { //在这里写上需要向外暴露的函数、变量
  add,
  basicNum
}

// 引用自定义的模块时,参数包含路径,可省略.js
const math = require('./math');
math.add(2, 5);

commonjs出来以后服务端的模块概念基本已经形成,但是commonjs是同步的方式加载模块,在服务端,模块文件都存在本地磁盘,读取可以很快完成同步加载,但是在浏览器端,限于网络原因,更合理的方案是使用异步加载。所以出现了异步模块加载AMD。

AMD

AMD是异步模块定义,采用异步方式加载模块,模块的加载不影响后面语句的运行,所有依赖这个模块的语句都定义在他的一个回调函数中,等加载完成之后再执行回调函数。同期推出了一个有名的库叫requirejs,他实现了AMD规范。AMD通过define函数来定义模块,通过requie函数来引入模块,第一个参数都是一个数组,数组中是依赖模块,第二个参数是一个回调,回调的参数是依赖模块的输出。

requirejs在申明依赖的模块时会在第一时间加载并执行模块内的代码,就会存在即使没用到某个模块还是会加载执行的情况

// utils.js
define([], function() {
    return {
        add: function(a, b) {
            console.log(a + b)        
        }    
    }
})
// main.js 文件
require(['./utils'], function(utils) {
    utils.add(1, 2)    
})
// 多个js文件存在依赖关系,需要提前加载所有的依赖
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) {
    // 等于在最前面声明并初始化了要用到的所有模块
    a.doSomething();
    if (false) {
      // 即便没用到某个模块 b,但 b 还是提前执行了
      b.foo()
    } 
})

CMD

CMD是另一种js模块化方案,它与AMD很类似,不同点在于:AMD 推崇依赖前置、提前执行,CMD推崇就近依赖、延迟执行。比如AMD会在申明依赖的第一个参数中列出所有的模块,CMD是在需要该模块的时候再进行require引入,从而实现了按需加载

/** AMD写法 **/
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) {
    // 等于在最前面声明并初始化了要用到的所有模块
    a.doSomething();
    if (false) {
        // 即便没用到某个模块 b,但 b 还是提前执行了
        b.doSomething()
    } 
})

/** CMD写法 **/
define(function(require, exports, module) {
  var a = require('./a'); //在需要时申明
  a.doSomething();
    if (false) {
        var b = require('./b');
        b.doSomething();
    }  
})

ES Modules

ES6 在语言标准的层面上,实现了模块功能,其模块功能主要由两个命令构成:export和import。

export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能

/** 定义模块 math.js **/
let basicNum = 0;
let add = function (a, b) {
    return a + b;
};
export { basicNum, add };

/** 引用模块 **/
import { basicNum, add } from './math';
add()
console.log(basicNum)

CommonJs 和 ES Modules的区别

 1. Commonjs模块输出的是一个值的拷贝,ES6模块输出的是值的引用

CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值

// main.js
let count = 0
function add () {
    count++
}
module.exports = { count, add }
// utils.js
let utils = require('./main')
utils.add() // 此时模块内部的count以发生改变
console.log(utils.count) // 但是模块内部的变化不会影响到值 依旧输出的是0

ES6模块输出的是值的引用。ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本执行时,再根据这个只读引用去模块中取值。即如果原始值变了,import加载的值也会变

// main.js
export let count = 0
export function add () {
  count++
}

// index.html
<script type="module">
    import { count, add } from './main.js'
    add()
    console.log(count) // 输出1
</script>

2.Commonjs模块是运行时加载,ES6模块是编译时输出接口

  • Commonjs加载的是一个对象(即module.exports属性),该对象只有在脚本运行完成才会生成,然后从这个对象上面读取方法,这种加载称为“运行时加载”
  • ES6模块不是对象,而是通过export命令显示指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载”

总结

模块化场景特点语法
CommonJSnode、webpack同步加载、磁盘读取速度快

导出:通过module.exports或exports导出

引用:require(' xx ')

AMD浏览器端,不常用异步加载,依赖前置,预先加载所有的依赖

导出:通过define定义模块

引用:require()

CMD浏览器端,不常用异步加载,依赖就近,按需加载

导出:通过define定义模块

引用:require()

ES Module目前浏览器端的默认标准静态编译

导出:通过export或export default输出模块

引用:import .. from 'xxx'

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

说说你对模块化的理解(CommonJS、AMD、CMD、ES Module) 的相关文章

随机推荐

  • Linux 下使用vscode调试C/C++程序记录

    Linux 下使用vscode调试C C 43 43 程序记录 本文主要介绍了 xff0c 在linux下使用vscode调试工程时的 xff0c 一些经验记录 基础配置 常用的配置方法网上的材料很多 xff0c 可以直接参照 链接 lin
  • 形状特征的提取

    物体和区域的形状是图像表达和图像检索中的另一重要的特征 但不同于颜色或纹理等底层特征 xff0c 形状特征的表达必须以对图像中物体或区域的划分为基础 由于当前的技术无法做到准确而鲁棒的自动图像分割 xff0c 图像检索中的形状特征只能用于某
  • c语言中全局变量在不同文件中的引用

    c语言中全局变量在不同文件中的引用 c语言中在某个文件中定义的全局变量可以在不同的文件中引用 xff0c 对数组和指针这两种全局变量在使用时必须要注意 xff0c 外部引用格式不正确时会出现编译或运行错误 下面通过不同的例子来说明数组和指针
  • Linux上MathGL的安装和使用

    Linux上MathGL的安装和使用 本人参考http mathgl sourceforge net doc en index html SEC Contents MathGL官网教程第一种方案在Ubuntu上对MathGL进行了编译安装
  • kvaser在linux下的二次开发

    kvaser在linux下的二次开发 linux下kvaser的驱动和SDK包安装 下载连接 http www kvaser cn software 7330130980754 V5 13 0 linuxcan tar gz 安装过程 解压
  • linux 交叉编译 C和C++

    linux 交叉编译 C和C 43 43 安装编译器Cmake中选择编译器编译运行注意 在ubuntu 中搭建arm交叉编译环境的过程记录 安装编译器 安装aarch64 linux gnu编译器 xff0c 可以参考 参考链接 安装完成后
  • vscode中git使用

    vscode中git使用 目的 xff1a 减少git的命令输出 xff0c 尽量使用vscode可视化完成日常代码提交管理 将该过程简单记录 创建文件 xff0c 并使用Vscode打开 vscode中打开终端 xff0c 并进行git的
  • 程序调试正常 运行错误排查

    调试正常 运行错误排查 检查是否生成core文件 输入ulimit a 第一行core file size 如果0 xff0c core文件不会生成 xff0c 需要设置 ulimit c unlimited 生成core文件 xff0c
  • linux 指定网卡发送UDP数据

    问题 xff1a 解决方法1 xff08 有权限要求 xff09 可以使用SO BINDTODEVICE绕过路由表查找 xff0c 解决该问题 注意 xff1a 该方法需要程序有cap net raw和cap net bind servic
  • TortoiseGit的安装与配置方法

    目录 1 为什么选择Git 效率 历史 TortoiseGit 简介 2 下载安装Git及Tortoisegit 3 Tortoisegit 配置 1 为什么选择Git 效率 很多人有一种习惯吧 xff0c 什么软件都要最新的 xff0c
  • Python isinstance() 函数

    描述 isinstance 函数来判断一个对象是否是一个已知的类型 xff0c 类似 type isinstance 与 type 区别 xff1a type 不会认为子类是一种父类类型 xff0c 不考虑继承关系 isinstance 会
  • uniapp开发微信小程序登录获取openid并解决code无效问题:invalid code

    场景 xff1a 实现微信支付的时候需要获取到openid openid需要在登录的时候用登录返回的code获取 1 登录获取code xff0c 用code获取openid uni login success function res l
  • CSS解决高度塌陷的方法

    一 什么是高度塌陷 当父元素不设置高度的时候靠子元素撑大 xff0c 也就是说子元素有多高 xff0c 父元素就有多高 xff0c 当子元素浮动后 xff0c 父元素就会高度塌陷 父元素高度塌陷后 xff0c 父元素下面的元素就会向上移动
  • mysql中如何查看sql语句是否用到索引,以及分析一条SQL的性能瓶颈

    mysql中如何查看sql语句是否用到索引 1 操作步骤 1 1 使用explain xff0c 放在sql前面 2 解释 我们只需要注意一个最重要的type 的信息很明显的提现是否用到索引 xff1a type结果值从好到坏依次是 xff
  • NoMachine配置

    NoMachine配置以及连接中遇到的问题 1 软件下载 软件官方下载网站 xff1a https www nomachine com xff08 软件下载缓慢 xff0c 请耐心等待下载完成 xff09 xff1b 本人上传了连个下载好的
  • 同星T1014在线回放设置

    同星T1014在线回放设置以及常见问题解决方法 1 同星T1014连接硬件进行在线数据回放 1 将同星T1014硬件连接到到电脑中 xff1b 2 打开TSMaster软件 xff0c 在通道选择选项中配置通道 xff0c 该硬件最大支持四
  • 虚拟串口VSPD和XCOM的下载+安装+使用

    虚拟串口VSPD和XCOM的下载 43 安装 43 使用 1 软件下载 对于上机位开发的伙伴来说 xff0c 上机位软件的调试尤为重要 xff0c 但是上机位软件的调试并不关心硬件 xff0c 只需要关注验证发送的数据的接收情况 xff0c
  • VCU功能控制

    VCU功能控制 VCU具有整车转矩管理 电池能量协调管理 电机功率协调管理 充电管理 故障诊断等功能 能够对上 下电时的高 低压控制逻辑进行管理 xff0c 能够根据驾驶员输入对需求转矩做出准确判断 xff0c 能够对车辆当前工况进行判断
  • 车速计算方法-附赠车速快速计算App

    车速计算的原理和方法 假设车辆配置为 xff1a 发动机WP10 310E40 xff0c 变速箱12JSD160TA 最高挡速比0 78 xff0c 车桥速比 xff1a 4 769 xff0c 轮胎11 00R20 滚动半径为0 527
  • 说说你对模块化的理解(CommonJS、AMD、CMD、ES Module)

    模块化的开发方式可以提高代码复用率 xff0c 方便进行代码的管理 通常一个文件就是一个模块 xff0c 有自己的作用域 xff0c 只向外暴露特定的变量和函数 目前流行的js模块规范有common js AMD CMD ES Module