拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ts-jest 的 stringifyContentPathRegex 选项:将 HTML 等文件内容字符串化为模块导入

ts-jest 的 stringifyContentPathRegex 选项:将 HTML 等文件内容字符串化为模块导入
  • 测试
  • 开发工具

【免费下载链接】ts-jest

A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript.

项目地址:https://gitcode.com/gh_mirrors/ts/ts-jest
点击查看免费下载

stringifyContentPathRegex是 ts-jest 提供的一个向后兼容配置项(其前身是globals.__TRANSFORM_HTML__),用于通过正则表达式匹配特定路径的文件,并将这些文件的原始内容直接导出为模块,而不是对它们进行 TypeScript 编译。本文将以 ts-jest 的 29.2 版本文档为核心,结合仓库源码,系统讲解该选项的用途、工作原理、三种配置写法以及必须注意的配套设置,帮助你快速在项目中落地"按原样导入 HTML 等文本资源"的能力。

选项是什么:为__TRANSFORM_HTML__而保留的兼容配置

stringifyContentPathRegex是一个正则表达式模式,用于匹配要被转换的文件的路径。它被保留下来,主要是为了兼容旧版 ts-jest 中的__TRANSFORM_HTML__全局配置。

  • 当某个文件的路径与该正则匹配时,该文件不会走正常的 TypeScript 编译流程;
  • 取而代之的是:该文件会被导出为一个导出其原始内容字符串的模块。

也就是说,匹配到的文件在运行时require/import得到的,是文件源码的字符串本身,而不是编译后的 JavaScript 逻辑。

从源码类型定义看,该选项在 ts-jest 配置中的形态为string | RegExp,见 src/types.ts:

export interface TsJestTransformOptions { // ... stringifyContentPathRegex?: string | RegExp }

因此,在 JS/TS 配置文件中可以直接写正则字面量,而在package.json这类纯 JSON 配置中则必须写成字符串(注意转义)。

工作原理:匹配路径,导出原文

官方文档给出了一个非常直观的例子:假设你有一个文件foo.ts,内容为export default "bar",并且你将stringifyContentPathRegex设置为foo\\.ts$。那么最终产出的模块不再是编译foo.ts源码的结果,而是一个导出字符串"export default \"bar\""的模块——即把源文件内容原样字符串化。

结合仓库源码可以更清楚地看到这条处理链路:

  1. 配置解析与正则归一化:在 src/legacy/config/config-set.ts 中,ts-jest 读取options.stringifyContentPathRegex:若传入的是字符串,则通过new RegExp(normalizeRegex(...))转换为正则;若本身就是RegExp,则直接使用。归一化后的正则保存在this._stringifyContentRegExp中。

  2. 路径判定:同一文件中的shouldStringifyContent(filePath)方法(src/legacy/config/config-set.ts)用这个正则去test文件路径,命中则返回true:

shouldStringifyContent(filePath: string): boolean { return this._stringifyContentRegExp ? this._stringifyContentRegExp.test(filePath) : false }
  1. 输出行为:仓库测试 src/legacy/ts-jest-transformer.spec.ts 用foo.html文件(内容为<h1>Hello World</h1>)配合stringifyContentPathRegex: '\\.html$'做了验证,最终产物为:
module.exports="<h1>Hello World</h1>"

可见,命中的文件内容被转义后作为字符串导出,模块消费者拿到的就是文件的原文。

三种配置写法:完整可运行的示例

官方文档提供了jest.config.js、jest.config.ts和package.json三种写法。下面完整继承并补充注释。

写法一:jest.config.js(推荐基于 preset 扩展)

// jest.config.js const { defaults: tsjPreset } = require('ts-jest/presets') /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { // [...] 其他配置 moduleFileExtensions: [...tsjPreset.moduleFileExtensions, 'html'], transform: { ...tsjPreset.transform, '\\.html$': [ 'ts-jest', { stringifyContentPathRegex: /\.html$/, }, ], }, }

写法二:jest.config.ts(基于 preset 扩展)

// jest.config.ts import type { JestConfigWithTsJest } from 'ts-jest' import tsJestPresets from 'ts-jest/presets' const jestConfig: JestConfigWithTsJest = { // [...] 其他配置 moduleFileExtensions: [...tsJestPresets.defaults.moduleFileExtensions, 'html'], transform: { ...tsJestPresets.defaults.transform, '\\.html$': [ 'ts-jest', { stringifyContentPathRegex: /\.html$/, }, ], }, } export default jestConfig

写法三:package.json 内联配置

// package.json { // [...] 其他字段 "jest": { "moduleFileExtensions": ["js", "ts", "html"], "transform": { "\\.(html|ts|js)$": [ "ts-jest", { "stringifyContentPathRegex": "\\.html$" } ] } } }

配置要点说明:

  • 在package.json(纯 JSON)中,正则必须写成字符串,注意转义:"\\\\.html$"在 JSON 解析后得到正则字符串\.html$。
  • 官方文档特别指出:jest.config.js版本完全可以仿照package.json版本手写配置;但从preset 扩展(如ts-jest/presets的defaults)会让配置在 ts-jest 升级时获得更好的兼容性,无需频繁改动。仓库中的预设实现可参考 presets/default/jest-preset.js 与 presets/index.js。
  • transform中传给 ts-jest 的第二个数组元素(对象),正是 ts-jest 的转换选项,stringifyContentPathRegex就在其中。

关键警告:必须保证 transform 与 moduleFileExtensions 的匹配

官方文档中的CAUTION值得单独强调:

无论你想用stringifyContentPathRegex匹配哪些文件,都必须确保 Jest 的transform选项中指向 ts-jest 的规则也能匹配这些文件。同时,可能还需要把这些文件的扩展名加入 Jest 的moduleFileExtensions选项。

这条警告包含两个互相配合的硬性前提:

  1. transform 规则必须覆盖目标文件:在示例中,transform里的'\\.html$'(或 package.json 写法的"\\.(html|ts|js)$")负责把.html文件交给ts-jest处理;stringifyContentPathRegex负责在 ts-jest 内部决定"这些文件是编译还是字符串化"。两者缺一不可——如果transform没匹配到.html文件,Jest 根本不会把它交给 ts-jest,stringifyContentPathRegex也就无从生效。
  2. 扩展名需加入moduleFileExtensions:Jest 默认的moduleFileExtensions通常只包含js、ts等,不含html。若不对目标扩展名做补充(例如示例中的'html'),Jest 在解析模块时可能找不到或无法正确识别这类文件。在 package.json 写法中这一项被显式写为["js", "ts", "html"],而在基于 preset 的写法中则是通过[...tsjPreset.defaults.moduleFileExtensions, 'html']在预设基础上追加。

迁移历史:从TRANSFORM_HTML到 stringifyContentPathRegex

stringifyContentPathRegex的前身是旧版 ts-jest 的globals.__TRANSFORM_HTML__。仓库中的向后兼容逻辑位于 src/utils/backports.ts:

if ('__TRANSFORM_HTML__' in globals) { warnConfig('globals.__TRANSFORM_HTML__', 'globals.ts-jest.stringifyContentPathRegex') if (globals.__TRANSFORM_HTML__) { mergeTsJest.stringifyContentPathRegex = '\\.html?$' } delete globals.__TRANSFORM_HTML__ }

可以看到:

  • 当检测到旧配置globals.__TRANSFORM_HTML__时,ts-jest 会打印一条废弃警告,并将其自动迁移为stringifyContentPathRegex;
  • 迁移时默认使用'\\.html?$'作为替换值(兼容.html与.htm两种扩展名);
  • 迁移完成后会删除旧的globals键,并提示可以使用 CLI 工具进一步整理配置。

因此,如果你正在维护使用__TRANSFORM_HTML__的老项目,升级到 29.2 后该行为依然可用,但应尽快迁移到新选项写法(即上文三种配置示例),以消除警告并获得后续版本更稳定的支持。

典型使用场景与建议

stringifyContentPathRegex的核心价值在于:让 ts-jest 项目中可以以原始字符串形式导入非 TypeScript 的文本资源。从实现机制(匹配路径 → 导出原文)可以推断,它特别适合以下场景:

  • 需要把 HTML 模板、SVG 片段等文本资源直接读入测试,并对其中的标签、属性、文案做断言;
  • 需要导入一些不希望被 TypeScript 编译或 Babel 处理、只想保持原文不变的资源文件;
  • 需要兼容历史上__TRANSFORM_HTML__所服务的 HTML 转换需求。

实践建议总结如下:

关注点建议
正则写法在 JS/TS 配置中直接写RegExp;在 JSON 中写带转义的字符串
transform 匹配确保把目标扩展名(如.html)纳入指向 ts-jest 的 transform 规则
moduleFileExtensions把目标扩展名追加到该数组,preset 基础上用展开语法追加即可
兼容旧配置让 ts-jest 自动迁移__TRANSFORM_HTML__,或手动改为stringifyContentPathRegex
验证效果运行测试,确认require/import得到的是文件原文字符串(如module.exports="..."形式)

如果你还没有配置过 ts-jest,可以先行阅读 website/docs/getting-started/options.md 了解全部可用选项,并结合 website/docs/getting-started/presets.md 选择基于 preset 的推荐配置方式。掌握stringifyContentPathRegex之后,导入 HTML 等文本资源将不再需要额外的 loader 或手写 readFile 辅助函数。

  • 测试
  • 开发工具

【免费下载链接】ts-jest

A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript.

项目地址:https://gitcode.com/gh_mirrors/ts/ts-jest
点击查看免费下载

相关推荐

上一篇:突破健康应用上架壁垒:Fastlane+Google Play政策合规实战指南
下一篇:RustDesk Server异步编程模型:Tokio在服务器中的应用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表