使用Jest测试时react-leaflet报SyntaxError: Unexpected token 'export'错误求助
问题:Jest测试时react-leaflet报SyntaxError: Unexpected token 'export'
代码正常运行,但使用Jest进行测试时,react-leaflet库抛出如下错误:
C:\node_modules\react-leaflet\lib\index.js:1 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { useMap, useMapEvent, useMapEvents } from './hooks.js'; ^^^^^^ SyntaxError: Unexpected token 'export' 9 | } from 'react-leaflet'; 10 | import { private } from 'private'; > 11 | | ^
相关配置文件
Jest配置
module.exports = { moduleNameMapper: { '.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy', '.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/__mocks__/file-mock.js', }, clearMocks: true, coverageDirectory: 'coverage', setupFilesAfterEnv: ['./src/setupTests.js'], coverageProvider: 'v8', globals: { 'ts-jest': { isolatedModules: true, }, }, rootDir: '.', moduleDirectories: ['node_modules', 'src', 'utils'], testEnvironment: 'jsdom', testTimeout: 20000, roots: ['<rootDir>/src'], testMatch: [ '**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)', ], transform: { '^.+\\.js?$': 'babel-jest', '^.+\\.(t|j)sx?$': ['@swc/jest'], }, moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], transformIgnorePatterns: [`/node_modules/(?!${esModules}')`], };
TsConfig
{ "include": [ "src/**/*.ts", "src/**/*.tsx", ], "exclude": [ "node_modules", "dist" ], "compilerOptions": { "target": "es2015", "module": "esnext", "declaration": true, "lib": [ "es2021", "es2017", "es2015", "dom", "ESNext" ], "allowJs": false, "jsx": "react-jsx", "sourceMap": true, "outDir": "dist", "rootDir": "src", "removeComments": true, "strict": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "resolveJsonModule": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "isolatedModules": true, "noEmit": true, "baseUrl": "src", "paths": { "test-utils": [ "./utils/test-utils" ] } } }
Babel配置
.babelrc
{ "presets": ["@babel/preset-env", "@babel/preset-react"] }
babel.config.js
module.exports = { presets: [ [ '@parcel/babel-preset-env', { targets: { esmodules: true, }, }, ], ], };
问题原因及解决方案
核心原因
Jest默认不会转译node_modules目录下的文件,但react-leaflet输出的是ES模块语法(export),而Jest运行在CommonJS环境中,无法直接识别该语法,导致报错。此外你当前的transformIgnorePatterns配置存在变量未定义的问题(${esModules}未声明),导致正则失效,无法正确指定需要转译的第三方包。
具体修复步骤
修复Jest的transformIgnorePatterns配置
修改Jest配置中的transformIgnorePatterns,明确指定需要转译的react-leaflet及其依赖包:transformIgnorePatterns: ['/node_modules/(?!react-leaflet|@react-leaflet/core|leaflet)'],这样Jest会对这些包进行转译,处理ES模块语法。
统一Babel配置
你当前存在两个Babel配置文件,可能导致冲突。修改babel.config.js,确保包含React转译预设,适配Jest环境:module.exports = { presets: [ ['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-react' ] };配置SWC支持JSX和ES模块
如果你使用@swc/jest,需要确保它能处理JSX和ES模块,在项目根目录创建.swcrc文件:{ "jsc": { "parser": { "syntax": "typescript", "jsx": true }, "transform": { "react": { "runtime": "automatic" } } } }可选:Mock react-leaflet组件
如果转译方案仍有问题,可以直接Mock react-leaflet的组件和钩子,避免加载真实库代码。在src/setupTests.js中添加:jest.mock('react-leaflet', () => ({ Map: () => <div data-testid="map" />, TileLayer: () => <div data-testid="tile-layer" />, useMap: jest.fn(), useMapEvent: jest.fn(), // 根据测试需求添加其他需要Mock的内容 }));
内容的提问来源于stack exchange,提问作者dcoates83
相关产品推荐
相关产品推荐

