前言

开门见山,首先 vitest 是一个 esm first 的测试工具,所以他的定位应该是 纯 esm / 纯 cjs 的场景,不像 jest 可以通过一些 transform 插件支持混杂场景。

什么是混杂场景,比如我们使用 typescript 编写 esm 格式的 source ,但是把产物编译为 commonjs 格式,最后给 node 调用,这在 Native ESM 普及之前是 node 库的基本操作。

当然现在有 type: "module" 带来了 typescript 编译的 esm 格式包和真正的 Native ESM 包。

我们这里不就 esm 话题展开聊,关键在于这种源码 esm 产物 cjs 是一种 混杂 场景。

这就违背了 vitest 的设计,不在 vitest 的概念内,所以自然无法使用 vitest 。

在混杂场景下,我不建议使用 vitest ,而使用 jest ,但如果非要使用 vitest 怎么办呢?我们有一种 workaround 的方法。

该方法的灵感和现在社区热导入 ts 文件的做法一致,也是 esno / swno / esbuild-jest 等库的底层原理。

底层逻辑剖析

在了解解法前,我们先简单剖析一下 vitest 不支持的底层逻辑。

由于 vitest 在底层使用 vite 的 esbuild 能力 transform ts 文件,所以关键在 esbuild 的配置。

当使用 cjs 作为产物的场景时
// vitest.config.tsimport { defineConfig } from 'vitest/config'export default defineConfig({esbuild: {target: 'node14',format: 'cjs'},
})

当我们把所有 transform 的 format 都定为 cjs 时,这将导致 *.test.ts 转换为 cjs 格式,这就意味着最终 *.test.ts 内会出现 ts 文件的导入:

// before: test file
// example.test.ts
import { method } from './some-file'// after: transformed result
// example.test.js
const { method } = require('./some-file')

注:以上转换为伪代码描述,并非真实结果。

其中 methodsome-file.ts 文件的一个变量,关键在于 require() 是无法正常导入一个 .ts 文件的,由此将引发:

Error: Cannot find module ‘./some-file’
Require stack:
- …

当使用 esm 作为产物的场景时
// vitest.config.tsimport { defineConfig } from 'vitest/config'export default defineConfig({esbuild: {target: 'node14',},
})

默认情况 vitest 是 esm 优先,所以我们的 test file *.test.ts 和相关导入的 .ts 文件会原模原样使用 esm 格式来处理,但别忘了我们使用 typescript 的产物是 cjs 格式,最终运行时是 cjs 而不是 esm ,这就导致了两者的概念发生冲突,将导致测试不符合预期,最终失败。

关于此处的错误可能是千人千面的,大多可能和 cjs 的导入报错相关,比如 TypeError: default is not a function 等。

解法

剖析完底层逻辑,我们来看解法。

在上文的剖析中,既然 require() 不能导入 .ts 文件,那么我们让他支持就好了。

在每次启动测试前人为 hook require.extensions 来支持 .ts 文件导入:

// hook.tsimport { EsbuildPhoenix } from '@xn-sakina/phoenix'// 这个类实现了 hook 对 .ts 文件的 require 导入并进行热转换
new EsbuildPhoenix({target: 'es2019'
})

vitest 配置:

// vitest.config.tsimport { defineConfig } from https://github.com/vitest-dev/vitestexport default defineConfig({test: {setupFiles: ['./hook']},esbuild: {target: 'node14',format: 'cjs'},
})

由此,我们便可以 workaround 掉这个问题。

进一步思考,还有什么没考虑到的?

  • 性能和 ts-jest / esbuild-jest 等 jest transform 插件实现思路一致,那么速度和 vitest 谁快?

  • hook require 的一个边缘情况是存在 require.cache ,如何应对?

  • 如何应对 .tsx 的 jsx element 场景?

  • 其他 edge case 是否都能无伤应对?

在此解法下,我顺利跑通了两大组非 jsx 测试,还是比较满意的。

但综合来看,仍然存在一些谜点待验证,我们还不能认为他是万能的解法。

总结

Migrating from jest

虽然 vitest 在混合场景可圈可点,但在这一切之前,我们还需要注意 migrating from jest 的方法,关于这一点,官方文档 有所描述,可以看到需要应对的点还是有不少的。

React strategy

值得注意的是,我还是建议在业务 React Project 场景使用 RTL ,因为更成熟,但简单的 libs jsx 场景可以使用 react-test-renderer ,这也是 vitest 推荐的做法。

Use native esm

同时,当你准备好拥抱 native esm 时,vitest 将是你不二的选择,你也可以在官方仓库 examples 找到更多的用例和打开姿势。

vitest支持cjs的workaround(TypeScript产物commonjs场景)相关推荐

  1. 雷军:小米MIX α量产难度太大已放弃;iPhone 12系列将支持北斗导航;TypeScript 4.0 RC发布|极客头条

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 国内要闻 雷军:小米MIX α量产难度太大,已放弃了 小米近 ...

  2. js 判断支持webgl_基于WebGL无插件虚拟场景漫游技术如何构建?ThingJS

    #三维可视化##3D开发# WebGL, ThingJS及3DSMAX 虚拟场馆漫游技术构建 基础组件 加载三维模型 实现虚拟漫游 渲染优化 如果要构建一个具有交互性和拓展性的沉浸式漫游场景,常用到3 ...

  3. Fluid 0.4 新版本正式发布:支持数据预热,优化小文件场景

    作者 | 顾荣 Photo Creidt @ 轻零 导读:为了解决大数据.AI 等数据密集型应用在云原生计算存储分离场景下,存在的数据访问延时高.联合分析难.多维管理杂等痛点问题,南京大学 PASAL ...

  4. js判断是否支持webgl_基于WebGL无插件虚拟场景漫游关键技术(完全版)ThingJS

    #三维可视化##3D开发# WebGL, ThingJS及3DSMAX 虚拟场馆漫游技术构建 基础组件 加载三维模型 实现虚拟漫游 渲染优化 如果要构建一个具有交互性和拓展性的沉浸式漫游场景,常用到3 ...

  5. CI130X智能语音芯片应用于智能面板,支持红外设备离线语音控制、场景控制等功能

    随着人们生活水平的提高,用户对产品的追求呈现多元化趋势,不仅仅只关注面板开关去控制的灯具亮灭,更注重产品的使用体验感.面板控制也演变了多种方式,从机械开关,轻触按键,手持遥控器到手机端APP,智能语音 ...

  6. 优雅简洁的通用排版利器:MarkDown(支持公众号、知乎等场景渲染)

    参考博文: 公众号和知乎排版神器 - mdnice.com 在线MarkDown编辑网站: mdnice Md2All mdnice的排版效果图: 含有简明的MarkDown格式说明,全程文字排版,非 ...

  7. ES Module 和 CommonJS 学习笔记(二) —— NodeJS 中使用 ESM 和 CJS

    在 NodeJS 中使用 ES6 模块 当前较新版本的 NodeJS 支持 ESM 和 CJS ,但默认使用的是 CJS 规范去解析 JS 代码,直接使用 CJS 是没有任何问题的,而使用 ESM 需 ...

  8. WebStorm 10支持TypeScript 1.4到JavaScript的实时编译

    JetBrains WebStorm 10支持在编辑代码的同时将TypeScript 1.4代码编译为JavaScript.新版本增加了对联合类型.模块.修饰符以及let和const关键字的支持.它还 ...

  9. vivado顶层模块怎么建_【第2040期】Node 模块化之争:为什么 CommonJS 和 ES Modules 无法相互协调...

    前言 又到周五了.今日早读文章由Shopee@周雨楠翻译授权分享. @周雨楠,Shopee金融事业群前端研发,自主学习前端技术3年,喜爱各类数字媒体技术.创意设计,多次参与翻译工作. 福利:有两张门票 ...

最新文章

  1. 英国JIC院士3.8万英镑招博后-植物代谢物与微生物组-截止6月27日
  2. windowsnbsp;下搭建apachenbsp;phpnbsp;mysqlnbsp;p…
  3. linux 服务器 安装网卡驱动,linux下安装编译网卡驱动的方法
  4. 往数据库的表中插入新行
  5. Java之Java程序与虚拟机
  6. Oracle常用字符串操作
  7. Spring Data JPA入门
  8. Unit01: Servlet基础 、 HTTP协议
  9. 周鸿祎和马化腾对话,泄露曝光
  10. 黑色背景的DW代码配色方案 Colors.xml
  11. cnpm下载依赖包速度快的原理探究
  12. 全新在线制图网站源码在线制作横幅广告
  13. linux移动硬盘hd0,怎样将UbuntuLinux系统放到移动硬盘?
  14. 字符串与整型的相互转换
  15. JVM七大垃圾回收器上篇Serial、ParNeW、Parallel Scavenge、 Serial Old、 Parallel Old、 CMS、 G1【尚】
  16. css之calc,CSS之calc()
  17. unity学习日志 第一天
  18. 一看就懂系列:java8流的扁平化/什么是扁平化流(图解)
  19. Gensim官方教程翻译(五)——英文维基百科的实验
  20. linux cp 中文文件名,linux下将中文文件名文件cp到windows目录下后文件名乱码问题的解决...

热门文章

  1. Eclipse安装官方中文补丁
  2. AP2403 DC-DC 降压恒流12-80V 四线高低亮爆闪 外置驱动方案
  3. 探迹CRM深度融合钉钉PaaS,实现营销全流程智能化管理
  4. 下一代VC运行时库——Universal CRT
  5. 秒懂边缘云 | CDN基础入门:访问控制及带宽阈值
  6. Science Advances|上海交大王风平团队揭示深古菌与早期地球协同演化历史
  7. 玩转数据结构(十三)构建BST
  8. Tech Summit 2018见闻:我们,MVP
  9. S7-200 Smart入门笔记7——中断2
  10. Android中aar和jar文件的认识