Jest テストで非標準構文エラーを解消:React Native + Expo 環境向け対策
主な問題点
Jest encountered an unexpected token
エラーは、次の状況で発生します:
- Jest が JSX/TSX 構文を処理できていない
node_modules
内のモジュールが正しくトランスパイルされていない- Jest 設定の競合や誤った環境設定が存在する
エラーが発生する根本原因
React Native/Expo 環境で Jest テストを実行する際に「SyntaxError: Unexpected token '<'
」が発生する主な原因は:
- JSX/TSX 構文の未処理: Jest はデフォルトで JSX を認識しない
- トランスパイル対象外モジュール:
node_modules
内の React Native 関連パッケージが Babel による変換対象外 - 設定の競合:
jest-expo
とts-jest
の同時使用による設定の衝突 - 不適切な環境設定: React Native 環境なのに
jsdom
が使用されている
効率的な解決策:設定ファイルの最適化
次の手順で jest.config.js
を修正します:
js
module.exports = {
// プリセットを統一(ts-jestではなくjest-expoを使用)
preset: "jest-expo",
transform: {
// TS対応のためts-jestを適用
"^.+\\.(js|jsx|ts|tsx)$": "ts-jest"
},
// テスト環境をreact-nativeに変更
testEnvironment: "react-native",
// Expo推奨の変換除外パターンを適用
transformIgnorePatterns: [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg))"
],
testPathIgnorePatterns: [
"<rootDir>/node_modules/",
"<rootDir>/.maestro/",
"@react-native"
],
setupFiles: ["<rootDir>/test/setup.ts"],
setupFilesAfterEnv: ["<rootDir>/jest-setup-after-env.js"]
};
キーポイントの説明
preset: "jest-expo"
既存のts-jest/presets
を削除し、Expo環境に最適化されたプリセットのみ使用testEnvironment: "react-native"
React Native環境に適したテスト環境を明示transformIgnorePatterns
の改善
Expo公式推奨パターンを採用し、必要なモジュールをトランスパイル対象に含む- 否定先読み
(?! ...)
の重要性
特定のnode_modules
をトランスパイル対象に含めるための正規表現技法
補足アドバイス
最適なtransformIgnorePatternsパターン
公式Expoドキュメントでは次のパターンが推奨されています(Unit Testing with Jest):
js
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg))"
]
プロジェクトで使用するライブラリに応じてパターンを適宜調整してください。
なぜこれで解決するのか
- JSX/TSX 処理の有効化
transform
設定により TypeScript/JSX ファイルが確実にトランスパイルされる - モジュール変換範囲の適正化
transformIgnorePatterns
で React Native 関連モジュールを変換対象に追加 - 環境の整合性向上
react-native
環境設定で Native モジュールの互換性を確保 - 設定競合の排除
プリセットの統一で設定が矛盾なく適用される
検証方法
修正後にテストを再実行:
bash
npx jest HelloWorld.spec.tsx
正常にレンダリングテストが実行され、以下のような出力が確認できるはずです:
text
PASS app/components/specs/HelloWorld.spec.tsx
HelloWorld
✓ renders (32 ms)
この設定は2023年10月時点の jest-expo
(v50+)、react-native
(v0.72+)、および公式Expoドキュメントに準拠した最新のベストプラクティスに基づいています。