Skip to content

Jest テストで非標準構文エラーを解消:React Native + Expo 環境向け対策

主な問題点

Jest encountered an unexpected token エラーは、次の状況で発生します:

  1. Jest が JSX/TSX 構文を処理できていない
  2. node_modules 内のモジュールが正しくトランスパイルされていない
  3. Jest 設定の競合や誤った環境設定が存在する

エラーが発生する根本原因

React Native/Expo 環境で Jest テストを実行する際に「SyntaxError: Unexpected token '<'」が発生する主な原因は:

  • JSX/TSX 構文の未処理: Jest はデフォルトで JSX を認識しない
  • トランスパイル対象外モジュール: node_modules 内の React Native 関連パッケージが Babel による変換対象外
  • 設定の競合: jest-expots-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))"
]

プロジェクトで使用するライブラリに応じてパターンを適宜調整してください。

なぜこれで解決するのか

  1. JSX/TSX 処理の有効化
    transform 設定により TypeScript/JSX ファイルが確実にトランスパイルされる
  2. モジュール変換範囲の適正化
    transformIgnorePatterns で React Native 関連モジュールを変換対象に追加
  3. 環境の整合性向上
    react-native 環境設定で Native モジュールの互換性を確保
  4. 設定競合の排除
    プリセットの統一で設定が矛盾なく適用される

検証方法

修正後にテストを再実行:

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ドキュメントに準拠した最新のベストプラクティスに基づいています。