Jest转换器在Typescript+Webpack+PEGJS环境下失效,导入值为undefined
Jest测试中PEGJS导入值为undefined的问题解决
项目配置
{ "scripts": { "test": "jest --config=jest.config.js" }, "devDependencies": { "@types/pegjs": "0.10.3", "@types/jest": "29.1.1", "ts-loader": "9.3.1", "raw-loader": "4.0.2", "typescript": "4.8.3", "webpack": "5.74.0", "webpack-cli": "4.10.0", "jest": "29.1.2", "ts-jest": "29.0.3" }, "dependencies": { "pegjs": "0.10.0" } }
项目特点
- 源码使用TypeScript编写
- 使用Webpack打包
- 集成PEGJS语法解析
- 使用Jest进行单元测试
项目结构
myproj |-src/ |-grammar.pegjs |-index.ts |-index.test.ts |-package.json |-jest.config.js |-transformer.js
测试配置与问题
项目中index.ts通过以下方式导入PEGJS语法文件:
import pegjsgrammar from './grammar.pegjs'
为了让Jest处理这类静态资源导入,自定义了transformer.js转换器:
const fs = require("fs"); module.exports = { process(sourceText, sourcePath, options) { const fileContents = fs.readFileSync(sourcePath, { encoding: "utf8" }).toString(); const json = JSON.stringify(fileContents).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'); return { code: `module.exports = ${json};`, }; }, };
并在jest.config.js中配置:
module.exports = { preset: "ts-jest", transform: { "\\.tsx?$": "ts-jest", "\\.jsx?$": "babel-jest", "\\.pegjs$": "<rootDir>/pegjs_jest_transformer.js" }, moduleFileExtensions: ["ts", "js", "pegjs"], };
运行测试时出现错误:index.ts中的pegjsgrammar值为undefined。
解决方案
1. 修正转换器路径配置
jest.config.js中配置的PEGJS转换器路径是<rootDir>/pegjs_jest_transformer.js,但实际转换器文件名是transformer.js,路径不匹配导致Jest无法加载转换器,进而无法正确处理PEGJS文件导入。
修改jest.config.js中的transform配置:
module.exports = { preset: "ts-jest", transform: { "\\.tsx?$": "ts-jest", "\\.jsx?$": "babel-jest", "\\.pegjs$": "<rootDir>/transformer.js" // 修正为实际文件名 }, moduleFileExtensions: ["ts", "js", "pegjs"], };
2. 优化转换器逻辑
转换器的process函数已经接收了sourceText参数(即PEGJS文件的内容),无需再通过fs.readFileSync读取文件,重复读取可能引发路径或权限问题。简化transformer.js:
module.exports = { process(sourceText) { const json = JSON.stringify(sourceText).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'); return { code: `module.exports = ${json};`, }; }, };
3. 添加TypeScript类型声明
TypeScript无法识别.pegjs文件的导入类型,需要添加类型声明文件以确保导入的语法正确性。在src目录下创建typings.d.ts:
declare module '*.pegjs' { const content: string; export default content; }
完成以上修改后,重新运行测试,pegjsgrammar即可正确获取到PEGJS文件的内容。
内容的提问来源于stack exchange,提问作者Andry
相关产品推荐
相关产品推荐

