ts-jest运行测试无法定位@vertigis/web模块报错如何解决
报错核心原因是Jest默认以CommonJS规范执行代码,且默认不会转译node_modules目录下的第三方依赖。你项目中用到的@vertigis/web、@arcgis/core均为ES Module格式发布,Jest直接解析这些包内的import语句就会抛出Cannot use import statement outside a module错误。你之前单独配置@vertigis/web/components的路径映射,既没有解决第三方ES Module包的转译问题,也没有覆盖所有用到的@vertigis/web子路径导入,自然会持续报错。
第一步:配置第三方ES Module包转译白名单
默认Jest会跳过所有node_modules下文件的转译,你需要把@vertigis、@arcgis相关的包加入转译范围,在jest.config.js中添加如下配置:transformIgnorePatterns: [ "node_modules/(?!(@vertigis|@arcgis)/)" ]该配置会告诉Jest:仅转译
node_modules下@vertigis、@arcgis开头的包,其余第三方包保持默认跳过逻辑,从根源解决ES Module语法解析报错。第二步:补全
@vertigis/web全路径映射规则
你的代码中用到了@vertigis/web/components、@vertigis/web/ui/*、@vertigis/web/models等多个子路径,只单独映射components路径必然会出现模块找不到的问题,替换原有moduleNameMapper规则为正则通用匹配:moduleNameMapper: { "^@vertigis/web/(.*)$": "<rootDir>/node_modules/@vertigis/web/$1" }该规则会自动匹配所有
@vertigis/web/开头的导入,映射到本地node_modules下的对应文件路径,不需要为每个子路径单独写配置。第三步:补全Jest转译与测试环境配置
确认jest.config.js中配置了ts-jest作为TS/TSX文件的转译器,同时将测试环境设置为jsdom以支持React组件渲染所需的浏览器DOM API:transform: { "^.+\\.(ts|tsx)$": "ts-jest" }, testEnvironment: "jsdom"第四步:Mock静态资源文件
@vertigis/web/ui下的组件会导入css、svg等静态资源,Jest无法直接解析这类文件,需要补充静态资源mock规则。首先在moduleNameMapper中新增规则:moduleNameMapper: { "^@vertigis/web/(.*)$": "<rootDir>/node_modules/@vertigis/web/$1", "\\.(css|less|scss|svg|png|jpg)$": "<rootDir>/src/__mocks__/fileMock.js" }然后在
src/__mocks__目录下新建fileMock.js,内容如下:module.exports = "test-file-stub";第五步:Mock Vertigis运行时上下文
@vertigis/web的组件、模型运行时依赖全局应用上下文,直接实例化模型、渲染组件会因为缺少上下文报错。测试时可以根据测试需求,对不需要验证逻辑的SDK导出做简易mock,或者在测试前初始化最小可用的SDK运行环境。
全部配置完成后,jest.config.js参考内容如下:
/** @type {import('jest').Config} */ module.exports = { preset: "ts-jest", testEnvironment: "jsdom", transformIgnorePatterns: [ "node_modules/(?!(@vertigis|@arcgis)/)" ], transform: { "^.+\\.(ts|tsx)$": "ts-jest" }, moduleNameMapper: { "^@vertigis/web/(.*)$": "<rootDir>/node_modules/@vertigis/web/$1", "\\.(css|less|scss|svg|png|jpg)$": "<rootDir>/src/__mocks__/fileMock.js" } };
重新执行npm run test即可解决之前的ES Module导入错误、模块找不到错误。
注意:不要为了解决ES Module报错在package.json中添加
"type": "module"配置,该配置会导致Jest、ts-jest的CommonJS逻辑异常,通过转译白名单处理第三方ES Module包即可。
内容的提问来源于stack exchange,提问作者MakePeaceGreatAgain

