Ionic 6+Angular 14配置Jest遇意外Token及@awesome-cordova插件问题
Ionic 6 + Angular 14 Jest 配置:解决HTML模板解析错误(JSX语法提示)
问题现象
在Ionic 6、Angular 14环境中配置Jest后,执行npm run test出现以下问题:
- Jest无法解析组件HTML模板,抛出「意外Token」错误,误将HTML识别为JSX并提示未启用JSX语法支持
- 收到ts-jest关于未知文件类型(HTML)的警告
原配置及报错信息
Jest.config.js
const { pathsToModuleNameMapper } = require('ts-jest'); globalThis.ngJest = { skipNgcc: false, tsconfig: 'tsconfig.spec.json', }; const esModules = ['@awesome-cordova-plugins', '@ionic','@ionic/core','@ionic/angular','@ionic-native','@angular/core','@angular','aws-amplify' ]; module.exports = { preset: 'jest-preset-angular', testEnvironment: 'jsdom', moduleNameMapper:{ "^aws-amplify": "<rootDir>/node_modules/aws-amplify/dist/aws-amplify.js", }, setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'], collectCoverage: true, testMatch: ['**/+(*.)+(spec).+(ts)'], testPathIgnorePatterns: [ "<rootDir>/node_modules/", "<rootDir>/dist/" ], transform: { '^.+\\.(ts|js|mjs|svg)$': 'jest-preset-angular', }, moduleFileExtensions: [ "ts", "tsx", "js", "jsx", "json", "node", ".html" ], transformIgnorePatterns: [ `<rootDir>/node_modules/(?!${esModules.join('|')})`, ], };
Setup-jest.ts
import 'jest-preset-angular';
Babel.config.js
module.exports = function (api) { process.env.NODE_ENV === "development" ? api.cache(false) : api.cache(true); const presets = [ [ "@babel/preset-env", { targets: { node: "current", }, }, ], "@babel/preset-typescript", ]; const plugins = ["@babel/plugin-transform-modules-commonjs"]; return { presets, plugins, }; };
报错信息
ielts@3.0.0 test jest ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information. ts-jest[ts-jest-transformer] (WARN) Got a unknown file type to compile (file: app\src\app\pages\side-menu-exp\side-menu-exp.page.html). To fix this, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match this kind of files anymore. FAIL src/app/pages/side-menu-exp/side-menu-exp.page.spec.ts ● Test suite failed to run Jest encountered an unexpected token Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. By default "node_modules" folder is ignored by transformers. Here's what you can do: • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. • If you need a custom transformation specify a "transform" option in your config. • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. You'll find more details and examples of these config options in the docs: https://jestjs.io/docs/configuration For information about custom transformations, see: https://jestjs.io/docs/code-transformation Details: SyntaxError: \app\src\app\pages\side-menu-exp\side-menu-exp.page.html: Support for the experimental syntax 'jsx' isn't currently enabled (1:1): > 1 | <ion-content> | ^ 2 | <!-- side hand menu starts --> 3 | <div class="side-nav-sect menuOpen" #sideMenu_content (click)="backdropDismiss($event)"> 4 | <div class="sde-nav-wrp"> Add @babel/preset-react (https://github.com/babel/babel/tree/main/packages/babel-preset-react) to the 'presets' section of your Babel config to enable transformation. If you want to leave it as-is, add @babel/plugin-syntax-jsx (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-jsx) to the 'plugins' section to enable parsing. 19 | @Component({ 20 | selector: 'app-side-menu-exp', > 21 | templateUrl: './side-menu-exp.page.html',
解决方案
1. 修正Jest配置文件
修改jest.config.js,添加HTML文件的转换规则和模块映射,调整文件扩展名配置:
const { pathsToModuleNameMapper } = require('ts-jest'); globalThis.ngJest = { skipNgcc: false, tsconfig: 'tsconfig.spec.json', }; const esModules = ['@awesome-cordova-plugins', '@ionic','@ionic/core','@ionic/angular','@ionic-native','@angular/core','@angular','aws-amplify' ]; module.exports = { preset: 'jest-preset-angular', testEnvironment: 'jsdom', moduleNameMapper:{ "^aws-amplify": "<rootDir>/node_modules/aws-amplify/dist/aws-amplify.js", // 映射HTML文件到Jest预设的存根,避免解析模板 '^.+\\.html$': 'jest-preset-angular/build/HTMLFileStub.js' }, setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'], collectCoverage: true, testMatch: ['**/+(*.)+(spec).+(ts)'], testPathIgnorePatterns: [ "<rootDir>/node_modules/", "<rootDir>/dist/" ], transform: { // 让jest-preset-angular处理HTML文件 '^.+\\.(ts|js|mjs|svg|html)$': 'jest-preset-angular', }, moduleFileExtensions: [ "ts", "tsx", "js", "jsx", "json", "node", "html" // 去掉扩展名前的点 ], transformIgnorePatterns: [ `<rootDir>/node_modules/(?!${esModules.join('|')})`, ], };
2. 调整TypeScript测试配置
修改tsconfig.spec.json,开启esModuleInterop解决ts-jest的导入警告:
{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": ["jest", "node"], "esModuleInterop": true }, "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] }
3. 移除冗余Babel配置(可选)
jest-preset-angular已内置Angular和TypeScript的转换逻辑,若没有特殊需求,可删除babel.config.js,避免配置冲突。
原理说明
- 添加HTML到
transform规则后,jest-preset-angular会正确处理Angular模板,不会将其误判为JSX HTMLFileStub.js作为模板存根,在测试中跳过实际HTML解析,提升测试效率- 开启
esModuleInterop解决第三方模块(如@awesome-cordova-plugins)的导入兼容性问题
内容的提问来源于stack exchange,提问作者santhosh
相关产品推荐
相关产品推荐

