Turborepo Monorepo中Jest测试React Native组件报错:Cannot use import statement outside a module
我特别理解你这种卡在配置上的挫败感——React Native + Turborepo + Jest的组合确实容易踩模块解析的坑,尤其是React Native自带的Flow代码处理部分。结合你给出的配置和已经尝试过的方案,我整理了几个针对性的修复步骤,你可以逐一尝试:
1. 先简化测试命令,关闭ES模块实验特性
你当前用了node --experimental-vm-modules node_modules/jest/bin/jest.js来启动测试,但React Native生态目前还是以CommonJS为主,启用VM模块反而会打乱Jest的模块解析逻辑。直接换成标准的Jest启动命令:
jest
或者在package.json的scripts里配置:
"scripts": { "test": "jest" }
2. 调整Babel配置,避免冲突并处理TypeScript
你的Babel配置里同时启用了metro-react-native-babel-preset和@babel/plugin-transform-modules-commonjs,容易导致重复转译冲突。改成只在测试环境启用CommonJS转译,同时添加TypeScript处理的预设:
/** @type {import('@babel/core').ConfigFunction} */ export default { presets: [ "module:metro-react-native-babel-preset", "@babel/preset-typescript" // 新增:让Babel处理TypeScript文件 ], plugins: [ "@babel/plugin-transform-flow-strip-types" ], env: { test: { plugins: ["@babel/plugin-transform-modules-commonjs"] // 仅测试环境转成CommonJS } } };
3. 重置Jest配置,用babel-jest统一转译
你当前混合使用了ts-jest的预设和react-native预设,容易出现兼容性问题。换成用babel-jest统一处理所有JS/TS文件,同时确保React Native相关包被正确转译:
import type {Config} from "jest"; const jestConfig: Config = { preset: "react-native", transform: { "^.+\\.(js|jsx|ts|tsx)$": "babel-jest" // 用Babel统一处理所有源码文件 }, transformIgnorePatterns: [ // 确保React Native及相关测试库的代码被转译,不被Jest忽略 "/node_modules/(?!(react-native|@react-native|@testing-library/react-native)/).*/" ], moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"], clearMocks: true // 可选:每次测试前清除mock,避免残留 }; export default jestConfig;
4. 处理pnpm的符号链接问题(如果是pnpm用户)
Turborepo + pnpm的组合可能因为符号链接导致Jest无法正确识别需要转译的包。在项目根目录的.pnpmrc文件里添加:
shamefully-hoist=true
这个配置会把所有依赖提升到根目录的node_modules,让Jest能正确找到并转译React Native相关的未编译代码。
最后验证
做完以上调整后,先删除node_modules和pnpm-lock.yaml(或package-lock.json),重新安装依赖:
pnpm install
然后再运行测试,应该能解决那个Flow代码的import语法错误了。
内容来源于stack exchange

