当前位置: 首页 > 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…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念&#xff1a; 1&#xff09;ZYNQ全称&#xff1a;ZYNQ7000 All Pgrammable SoC 2&#xff09;SoC:system on chips(片上系统)&#xff0c;对比集成电路的SoB&#xff08;system on board&#xff09; 3&#xff09;ARM&#xff1a;处理器…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...

flow_controllers

关键点&#xff1a; 流控制器类型&#xff1a; 同步&#xff08;Sync&#xff09;&#xff1a;发布操作会阻塞&#xff0c;直到数据被确认发送。异步&#xff08;Async&#xff09;&#xff1a;发布操作非阻塞&#xff0c;数据发送由后台线程处理。纯同步&#xff08;PureSync…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...