当前位置: 首页 > news >正文

前端架构: 脚手架通用框架封装之CommonJS和ESM混合开发兼容解决(教程五)

CommonJS 和 ESModule 混合开发

  • 接上文,仍旧在 abc-cli 项目中
  • 参考:https://blog.csdn.net/Tyro_java/article/details/136433159
  • 现在要在脚手架项目中安装 chalk 依赖,因为在 abc-cli 项目几乎都是 CommonJS的实现
  • 而 chalk 这个依赖源码是基于 ESModule 的,所以现在要解决的是两者的兼容
  • 先安装 chalk 到 cli 包中,在 abc-cli 目录下,$ npm i chalk -w packages/cli
  • 但是,在使用 chalk 的时候,就会报错,不能使用 require,现在有几种解决方案
    • 第一种,降级 chalk 到低版本, 大概在4.0左右,但是这就无法使用 chalk 的新特性了
    • 第二种,修改自己的代码,将之前的 require 全部修改成 import, 并且package.json中添加 "type":"module"
      • 这种会造成更大的问题:一是,之前的语法全部要修改,包括 module.exports
      • 二是,如果要使用一些只有 CommonJS 的依赖就会有问题
    • 第三种,在CommonJS中允许使用 import 来加载依赖,但是 import 返回了一个 Promise
      • 这种,只能异步拿到真实的依赖,就不好处理了
  • 现在遇到了一个问题,就是如何兼容 CommonJS 和 ESModule, 怎样才能最佳实践
  • npm 模块有的使用CommonJS, 有的使用 ESM, 两者混合开发成为 Nodejs 项目必须考虑的问题

1 )CommonJS

  • CommonJS 单独使用有两种方式
    • 1 )在 package.json 中指定 "type": "common" 这个不指定也是默认的
    • 所有js文件的的导入都用 require 语法来引用模块
    • 所有js文件的导出都用 module.exports 语法来导出
    • 2 )不管 package.json 中指定的是 "type": "common" 亦或是 "type": "module"
    • 只要js文件的后缀是 .cjs 都可以使用 requiremodule.exports 语法
    • 这样,默认走的就是 CommonJS 规范
  • 注意,module.exportsexports.xx 不能混用,两者混用,后者不生效
  • CommonJS规范默认通过自执行函数实现,比如require源码,它可以做一些变量注入
  • 比如 __dirname, __filename 都是通过注入的方式来显示的
  • 可以把它们直接打印出来

2 )ESModule

  • ESModule 也有两种使用方式
    • 1 )在package.json中定义 "type": "module",包内所有 .js 文件会被认为是 ESModule
    • 2 ).mjs 后缀的文件,强制被认定为 ESModule
  • 在ESModule中导出 export default {},导入 import
  • 在这里,__dirname, __filename 这种API,统统不支持,但是网上也有兼容方案,这里先不研究
    • 除了网上的一些解决方案,这里暂时提供一个第三方库来解决 dirname-filename-esm

3 )CommonJS 和 ESModule 混用

  • 原则上,不应该混用,一般我们开发包的时候,需要指定一种
  • 单个模块,必须指定CommonJS 或 ESM, 如果混用,必须用webpack或babel来解决
  • 另外,package.json 的 type 可以不写,如果写就必须指定一种,默认是 commonjs
  • 越来越多的模块采用了 ESModule, 也就是指定 type 为 module

3.1 在 CommonJS 中引用 ESM

  • 如果一个模块是ESM, 比如,它叫 “esm” 来举例
    import('esm').then(esm => esm.default())
    
  • 这种做法非常别扭
  • CommonJS 本身是一个同步的规范,require 它的实现是一个同步加载模块的方案
    • 它在模块外围包一层自执行函数,是同步方案实现的
    • 参考:https://blog.csdn.net/Tyro_java/article/details/53574887
  • ESM 本身用的是 import 用的是异步方式来加载,和CommonJS是完全不同的两种实践方案
  • 如果是 在 CommonJS 中引用 ESM,那么代码就会非常的奇怪
  • 要想实现同步操作,就必须加一个自执行函数,并将这个函数指定为 async 方式
    (async function() {const esm = await import('esm');esm.default();
    })()
    
    • 这样,很麻烦,也很奇怪
    • 但是能解决问题

3.2 在 ESM 中引用 CommonJS

  • 在 ESM 包中,不管依赖是 ESM还是CommonJS方案开发的,都可以直接 import
  • 假设 “cjs” 是一个 CommonJS 模块的方案
    imort cjs form 'cjs';
    
  • 所以,推荐把源码全部移植到ESM模块中

常见的报错问题和解决

  • 1 )未指定 package.json 中的 type, 但是使用了 importexport 语法

    • 这是缺失了 package.json 中 type 默认是 commonjs 的知识点造成的
  • 2 )require 语法无法加载ESM模块

    • 必须使用 import 来加载ESM模块
  • 3 )ESM 去加载其他ESM模块时会有找不到模块的报错

    • 没有构建工具时,import的时候需要添加后缀,不能省略
    • 注意,还有导出用 export default 时,引入时别忘记了这个 default

相关文章:

前端架构: 脚手架通用框架封装之CommonJS和ESM混合开发兼容解决(教程五)

CommonJS 和 ESModule 混合开发 接上文,仍旧在 abc-cli 项目中参考:https://blog.csdn.net/Tyro_java/article/details/136433159现在要在脚手架项目中安装 chalk 依赖,因为在 abc-cli 项目几乎都是 CommonJS的实现而 chalk 这个依赖源码是基…...

基于主从模式的Reactor的仿muduo网络库

🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风…...

Linux服务器搭建超简易跳板机连接阿里云服务器

简介 想要规范内部连接阿里云云服务器的方式,但是最近懒病犯了,先搞一个简易式的跳板机过渡一下,顺便在出一个教程,其他以后再说! 配置方法 创建密钥 登录阿里云,找到云服务器ECS控制台,点击…...

Windows Server 各版本搭建文件服务器实现共享文件(03~19)

一、Windows Server 2003 打开服务器,点击左下角开始➡管理工具➡管理您的服务器➡添加或删除角色 点击下一步等待测试 勾选自定义配置,点击下一步 选择文件服务器,点击下一步 勾选设置默认磁盘空间,数据自己更改,最…...

ARM总结and复习

安装交叉编译工具链 a. 为什么安装 因为arm公司的指令集在不断迭代升级,指令集日益增多,而架构是基于指令集研发的,所以架构不一样,指令集也不一样 eg:arm架构使用的是arm指令集 x86架构使用的是x86指令集 而我们日常开发环境中linux的架构…...

非功能测试的定义、类型和示例

软件已从推动者转变为不同行业企业成功的核心支柱。因此,非功能测试活动成为人们关注的焦点。然而,许多技术和质量保证专业人员并没有意识到非功能测试的必要性。 他们必须了解什么是非功能测试以及为什么必须鼓励将其作为企业应用程序开发项目的实践。…...

Angular基础---HelloWorld---Day1

文章目录 1. 创建Angular 项目2.对Angular架构的最基本了解3.创建并引用新的组件(component)4.对Angular架构新的认识(多组件)5.组件中业务逻辑文件的编辑(ts文件)6.标签中属性的绑定(1) ID的绑定(2) class…...

k8s部署项目常见的问题及解决方案

在Kubernetes(k8s)部署项目中,确实存在一些常见问题和挑战。以下是这些问题及其相应的解决方案: 网络插件问题: 问题:网络插件配置不当或版本不兼容可能导致Pod间通信问题。解决方案:重新部署或…...

Redis实现乐观锁+秒杀场景demo

在Redis中,乐观锁通常是通过使用 WATCH、MULTI 、EXEC和DISCARD命令实现的。这种乐观锁机制允许客户端在执行事务期间监视一个或多个键,并且只有在事务执行期间没有其他客户端修改被监视的键时,才会执行事务。 应用场景: 库存控…...

阅读笔记 | Transformers in Time Series: A Survey

阅读论文: Wen, Qingsong, et al. “Transformers in time series: A survey.” arXiv preprint arXiv:2202.07125 (2022). 这篇综述主要对基于Transformer的时序建模方法进行介绍。论文首先简单介绍了Transformer的基本原理,包括位置编码、多头注意力机…...

WPF MVVM中List<>和ObservableCollection<>的区别与对比分析

在WPF MVVM&#xff08;模型-视图-视图模型&#xff09;架构中&#xff0c;数据绑定是实现UI与后端逻辑分离的关键特性。为了使UI能够响应后端数据的变化&#xff0c;通常需要用到特定的集合类型。在WPF中&#xff0c;最常见的两种集合类型是List< T>和ObservableCollect…...

python给企微发消息

方法一&#xff1a;webhook方式。使用群机器人给企微群发消息 import requestsdef qwxsendmessage(msg):urlhttps://qyapi.weixin.qq.com/cgi-bin/webhook/send?key6c598840-804a-4eb5-a999-a023313 #url换成自己群机器人的webhookurldata{msgtype:text,text:{content:msg}}…...

TCP/IP状态迁移

TCP&#xff08;传输控制协议&#xff09;是一种面向连接的流式控制协议&#xff0c;它定义了不同的状态以管理通信过程中的连接。TCP 状态迁移描述了 TCP 连接在不同状态之间的转换过程&#xff0c;常见的 TCP 状态包括 CLOSED、LISTEN、SYN_SENT、SYN_RECEIVED、ESTABLISHED、…...

C语言实现各类排序算法

排序算法是计算机科学中的一个重要概念,它是一种将一个无序的数列重新排列成有序的方法。常见的排序算法有: 选择排序&#xff08;Selection Sort&#xff09; 选择排序是一种简单直观的排序演算法。它的工作原理:首先在未排序序列中找到最小(大)元素&#xff0c;存放到排序序…...

Network LSA 结构简述

Network LSA主要用于描述一个区域内的网络拓扑结构&#xff0c;包括网络中的路由器和连接到这些路由器的网络。它记录了每个路由器的邻居关系、连接状态以及连接的度量值&#xff08;如带宽、延迟等&#xff09;&#xff0c;以便计算最短路径和构建路由表。display ospf lsdb n…...

揭示IP风险画像的作用与价值

在当今数字化时代&#xff0c;互联网的快速发展为企业和个人带来了巨大的机遇&#xff0c;同时也带来了各种安全风险和威胁。随着网络攻击手段的不断升级和演变&#xff0c;传统的安全防御手段已经无法满足对抗复杂多变的网络威胁的需求。IP风险画像作为一种新型的网络安全解决…...

[python] dataclass 快速创建数据类

在Python中&#xff0c;dataclass是一种用于快速创建数据类的装饰器和工具。自Python 3.7起&#xff0c;通过标准库中的dataclasses模块引入。它的主要目的是简化定义类来仅存储数据的代码量。通常&#xff0c;这样的类包含多个初始化属性&#xff0c;但没有复杂的方法&#xf…...

opencv实现图像的融合

实现图像的融合并且输出一张jpg格式的照片。 先显示一个彩色图的照片 然后我以彩色方式读取1.png&#xff0c;以灰度图方式读取3.png这张图片&#xff0c;并且用两个窗口独立地去显示(我后来发现不能把灰度图和彩色图相融合) 然后实现两个融合 #include <opencv2/highgu…...

Orbit 使用指南 02 | 在场景中生成原始对象| Isaac Sim | Omniverse

如是我闻&#xff1a; Orbit使用指南02将 深入探讨如何使用Python代码在Orbit中向场景生成各种对象&#xff08;或原始对象&#xff09;。一起探索如何生成地面平面、灯光、基本图形形状以及来自USD文件的网格。前置知识&#xff1a;如何生成空白场景&#xff0c;Orbit 使用指…...

【2024】利用python爬取csdn的博客用于迁移到hexo,hugo,wordpress...

前言 博主根据前两篇博客进行改进和升级 利用python爬取本站的所有博客链接-CSDN博客文章浏览阅读955次&#xff0c;点赞6次&#xff0c;收藏19次。定义一个json配置文件方便管理现在文件只有用户名称,后续可加配置读取用户名称&#xff0c;并且将其拼接成csdn个人博客链接ty…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Java并发编程实战 Day 11:并发设计模式

【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天&#xff0c;今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案&#xff0c;它们不仅提供了优雅的设计思路&#xff0c;还能显著提升系统的性能…...

【java】【服务器】线程上下文丢失 是指什么

目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失&#xff1f; 直观示例说明 为什么上下文如此重要&#xff1f; 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程&#xff0c;代码应该如何实现 推荐方案&#xff1a;使用 ManagedE…...

Docker、Wsl 打包迁移环境

电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本&#xff1a; 2.2.4.0 内核版本&#xff1a; 5.15.153.1-2 WSLg 版本&#xff1a; 1.0.61 MSRDC 版本&#xff1a; 1.2.5326 Direct3D 版本&#xff1a; 1.611.1-81528511 DXCore 版本&#xff1a; 10.0.2609…...

Ray框架:分布式AI训练与调参实践

Ray框架&#xff1a;分布式AI训练与调参实践 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 Ray框架&#xff1a;分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...