关于commonjs、AMD、UMD、ESM以及ts模块之间的使用差异

news2025/7/28 6:08:04

commonjs

特点:一个文件就是一个模块,拥有独立的作用域,适用于服务端不适合浏览器端。导出模块内部数据通过module.exports或exports对象默认导出:

// true
const a = 1
const b = 2
module.exports = {
  a, b
}

或者

// true
const a = 1
const b = 2
exports.a = a
exports.b = b

module.exports等于exports这个对象,不能改变exports对象的指针方向。

// false
const a = 1
const b = 2
exports = {
	a,
	b
}

AMD

特点:浏览器端没有具体实现该规范的代码,需要使用define配合requireJS来实现。一个define就是一个模块。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./require.js" data-main="./a.js"></script>
  </head>
</html>
// 导出
// b.js
define(function () {
  'use strict';
  const c = 3
  const d = 4
  return {
    c,
    d
  }
});
// 或者
define(function (require, exports, module) {
  'use strict';
  const c = 3
  const d = 4

  module.exports = {
    c,
    d
  }
});

// 导入
// a.js 依赖前置
define(['./b'], function (b) {
  console.log(b);
});
// 或者 后置依赖
define(function (require, exports, module) {
  const b = require('./b')
  console.log(b);
});

UMD

UMD的出现是为了同时兼容node端和浏览器端。

(function (root, factory) {
  if (typeof module === 'object' && typeof module.exports === 'object') {
    // node
    module.exports = factory()
  } else if (typeof define === 'function' && define.amd) {
    // 浏览器
    define(factory)
  } else {
    // 既不是浏览器也不是node
    root.factory = factory
  }
})(this, function () {
  const a = 1
  const b = 2
  return {
    a, b
  }
})

ESM

一个文件就是模块,拥有独立的作用域,script标签需要声明type=“module”。
导出模块数据:

// 单个导出
export let a = 1
export let b = 2
// 导出列表
export {a,b}
// 重命名导出
export {a as one,b as two}
// 默认导出
export default {a,b}
export {a as default,b as two}
// 重定向导出
export * from './a'
export {a,b} from './a'
export { default } from './a'

TS模块系统

typescript有一套自己的模块系统,类似esm,以一个文件作为模块最小单元:

  • 任何一个包含顶级import或者export的文件都被当成一个模块
  • 如果一个文件不带有import 或者export ,那么它的内容就是全局的

全局模块(不推荐)

// index.ts
let a = 1
let b = 2

// index2.ts error
let a = 1

// index2.ts true
let a = 1
export default {}

在这里插入图片描述
当我们在两个不同的文件中重复声明同一个变量的时候如果没有使用顶级import或者export 那么就是全局声明导致重复声明。

导入js文件

// b.js commonjs导出方式
module.exports = {
  a: {
    b: 1
  }
}
// a.js 默认引入
import m from './b.js'
console.log(m);
编译后会报错,此时配置allowSyntheticDefaultImports:true"use strict";
exports.__esModule = true;
var b_js_1 = require("./b.js");
console.log(b_js_1["default"]);

引入的方式是默认引入,需要默认导出才能引入(或者import * as m from './b.js' m={ a: [Getter], default: { a: { b: 1 } } } )。使用默认导出编译后可以看出获取了该对象的default属性,commonjs的方式没有default。所以tsconfig.json可以配置esModuleInterop:true的方式解决:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
  return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var b_js_1 = __importDefault(require("./b.js"));
console.log(b_js_1.default);

模块解析规则

typescript支持两种不同的模块解析策略:Node、Classic。当module为:AMD、System、ES2015的时候,默认为Classic,否则为node。也可以设置moduleResolution为node。typescript现在使用了与Node.js类似的模块解析策略,但是Typescript增加了其他几个源文件扩展名的查找(.ts、.tsx、.d.ts),同时Typescript在package.json里使用types去表示main的意义。

Classic模块解析策略

  1. 相对导入
// src/a.ts
import a from './a.ts'
解析流程:
1.src/a.ts
默认补全后缀
import a from './a'
解析流程:
1./src/a.ts
2./src/a.d.ts
  1. 非相对导入
import a from 'a'
从包含文件目录开始依次向上级目录遍历查找,直到根目录
1./src/a.ts
2./src/a.d.ts
3./a.ts
4./a.d.ts

Node解析策略

  1. 相对导入
// src/a.js
import a from './a'
解析流程:
1.src/a.js
2.src/package.json中指定的文件
3.src/index.js
  1. 非相对导入

非相对导入中会在node_modules里查找,并从当前目录的node_modules目录下逐级向上级文件夹查找。

// src/a.js
import a from 'a'
解析流程:
1.src/node_modules/a.js
2.src/node_modules/package.json中main指定的文件
3.src/node_modules/index.js
4.node_modules/a.js
5.node_modules/package.json中main指定的文件
6.node_modules/index.js

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

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

相关文章

【跨境电商卖家】Instagram营销初学者指南(二):方法与技巧

关键词&#xff1a;跨境电商卖家、instagram营销 1.为 Instagram营销设定目标 在你开始在 Instagram 上发帖之前&#xff0c;问问你自己&#xff08;或你的团队&#xff09;一件事&#xff1a;你为什么在 Instagram 上&#xff1f;尽管该平台很受欢迎&#xff0c;但您的回答不…

linux笔记(6):东山哪吒D1H显示HDMI测试-命令行调试

文章目录1.测试流程和结果2.测试过程详解2.1 挂载测试工具1.2 设置参数1.2.1设置name1.2.2选择命令1.2.3 设置命令参数1.3开启显示3.还没搞清楚怎么在应用中显示字符测试开发板的HDMI输出。 参考文档&#xff1a;全志官方文档。 1.测试流程和结果 测试结果&#xff1a; 2.测…

如何实现一键全选

利用复选框的激活、非激活实现一键全选功能 效果展示 前置准备 投票列表素材 具体步骤 添加素材 制作列表复选框 制作一件全选按钮 创建复选框相关行为触发器 制作一键全选触发器 步骤分解 添加素材 拖拽 图片组件 到 根容器 选中 图片组件 铺满父级容器 点击 检查面板 中的 …

一种新的群体智能优化算法:麻雀搜索算法(SSA)(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

C++中函数调用的整个过程内存堆栈分配详解

函数调用过程中&#xff1a;实参将值拷贝给函数的形参&#xff0c;而函数的形参相当于一个生存周期位于函数 内部的局部变量&#xff0c;函数内部的内存操作也只是将拷贝到形参的值进行操作&#xff0c;形参在函数结束 后会被栈自动回收释放(形参在栈中分配)&#xff0c;这就是…

Spring Security如何防止会话固定攻击

在春季安全课程的这篇文章中&#xff0c;我们将研究春季安全会话固定以及如何防止春季应用程序中的会话劫持。 春季安全会话固定 会话固定是一种非常常见且最常见的攻击类型&#xff0c;恶意攻击者可以通过访问站点来创建会话&#xff0c;然后诱使其他用户使用相同的会话登录…

副业是刚需?分享几个程序员接外包私活的网站

经常看到某某程序员接了个项目开发&#xff0c;工作之余轻轻松松赚了钱还顺带提升了技术&#xff1b;或者看到某大佬又发表了一篇程序员技术提升稿件&#xff0c;阅读点赞收藏三连发&#xff0c;这个月的零花钱又不愁了...但自己只是一名普普通通的程序员&#xff0c;能找到这样…

Golang入门笔记(10)—— 闭包 closure

先看一段代码&#xff0c;脱离代码讲闭包&#xff0c;太干了。 package mainimport "fmt"func main() {a : Adder()fmt.Println(a(1))fmt.Println(a(2))fmt.Println(a(3)) }func Adder() func(int) int { // 累加器&#xff1a;这里从10开始累加var sum int 10retu…

linux时区相关

背景&#xff1a;用linux自带的时间接口函数读取时间的时候&#xff0c;发现有时候时间与北京时间不符合&#xff0c;经过研究发现&#xff1a;时间 UTC时间时区带来的偏移。操作方法&#xff1a;timedatectl list-timezones可看支持的时区改时区方法有如下两种&#xff1a; l…

【LeetCode 每日一题】15. 三数之和

01 题目描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元…

【数据结构】链表LinkedList

1.ArrayList的缺陷 2.单链表的实现 3.LinkedList的使用&#xff08;模拟实现&#xff09; 我们之前介绍过ArrayList了&#xff0c;它的底层是数组&#xff0c;数组是一段连续的空间&#xff0c;当我们想要插入或者删除数据的时候&#xff0c;插入元素&#xff0c;就要让插入位置…

用树莓派PICO做一个桌面时钟超详细教程!

用树莓派PICO做一个可显示时间和温湿度的桌面时钟一、概述二、材料准备1、树莓派PICO2、DHT11温湿度传感器3、DS1302时钟模块&#xff08;选用&#xff09;4、SSD1306屏幕5、其他材料三、开始1、连线2、写程序&#xff08;1&#xff09;使用内置RTC函数实现的时钟&#xff08;2…

2.11 教你一套怎么建立自己的选题素材库的方法【玩赚小红书】

一、自身定位延伸选题库 建立选题库&#xff0c;前提先确定自身定位&#xff0c;然后发散性思维延展。如我们做母婴博主&#xff0c;接下来就要想&#xff0c;母婴用户会关注什么&#xff0c;自然会想到到宝宝吃喝玩乐、妈妈保养、产后修复、婆媳关系等等内容。若我们只做宝宝…

这才是,真彩虹预染蛋白Markers

做WB的小伙伴都知道&#xff0c;现市面上各种“多彩”Marker的产品有很多&#xff0c;但是真正拿到手上的&#xff0c;可能是各种各样的&#xff08;见图1&#xff09;&#xff0c;咱也不清楚哪个是真的... 现在小编告诉你&#xff0c;经典的彩虹Marker长这样(见图2)&#xff1…

WebDAV之葫芦儿·派盘+读出通知

读出通知 支持webdav方式连接葫芦儿派盘。 手机各种推销通知太多,如何避免那些繁琐的通知内容,做出一键就能够阅读重要通知的最佳体验,帮助您更加快速和便捷的体验到那些应用内容?推荐大家使用读出通知。 读出通知APP可以设置接收通知的app,还可以用耳机操作,操作简单…

avalanche 少量tcp长连接持续构建HTTP请求测试

最近测试项目&#xff0c;测试要求使用少量tcp长连接连接&#xff0c;持续打HTTP请求&#xff0c;到测试结束。 分别用思博伦测试仪和supernova测试仪进行实现。 思博伦测试仪实现 测试仪基本运行流程&#xff1a;Loads配置任何形式bandwidth&#xff0c;connection&#xf…

SpringBoot项目本机和Linux环境部署

文章目录一. 本机环境下打包与运行二. Linux下部署SpringBoot项目2.1 Linux环境配置2.2 配置数据库2.3 运行程序一. 本机环境下打包与运行 项目进行打包 2. 本机环境下运行SpringBoot程序 控制台进入SpringBoot项目jar包所在的文件夹&#xff0c;运行下面指令即可 java -jar […

[附源码]java毕业设计企业招标系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

JDBC技术

JDBC 一、jdbc的概述 JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口&#xff08;一组API&#xff09;&#xff0c;定义了用来访问数据库的标准Java类库&#xff0c;&#xff08;java.sql,javax.sql&#xff09;使用…

第十一周周报

学习目标&#xff1a; DDPM 学习内容&#xff1a; DDPM代码 学习时间&#xff1a; 11.13-11.18 学习产出&#xff1a; 一、DDPM 1、trainer trainer用来计算损失&#xff0c;即将图片加噪后计算损失&#xff0c;损失公式如下&#xff1a; extract()函数&#xff1a;…