RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-04-08中級

Rork Max アプリでExpo Goプレビューと実機ビルドの動作が違う:よくある原因と解決法

Rork MaxアプリをExpo Goでプレビューすると動くのに、実機ビルドや本番環境で動かないというトラブルの原因を解説。フォント・ネイティブモジュール・環境変数・APIエンドポイントの不一致を解決します。

Rork Max229Expo Goビルドエラー8トラブルシューティング77React Native209実機テスト13EAS Build14

Rork Max アプリでExpo Goプレビューと実機ビルドの動作が違う:よくある原因と解決法

Rork Maxでアプリを開発していると、Expo Goでのプレビューでは完璧に動いているのに、本番ビルドや実機でテストすると急に動かなくなる……という体験をすることがあります。

「プレビューで確認したのにリリース後にクラッシュした」「Expo GoではUIが正しく見えるのにビルドすると崩れる」——このような問題は、Expo GoとネイティブビルドのRuntimeの違いに起因していることがほとんどです。

Expo Goとネイティブビルドの根本的な違い

まず前提として、Expo GoとEAS Build(またはexpo buildによるネイティブビルド)の違いを理解する点が肝心です。

Expo Goは事前にコンパイルされたExpoのシェルアプリで、JavaScript(またはTypeScript)のみを実行します。ネイティブモジュールはExpo SDKが提供するものだけが使えます。

EAS Build / ネイティブビルドは実際のApp Store配布向けバイナリを生成します。app.json/app.config.jsの全設定が反映され、カスタムのネイティブコードを含む本番アプリです。

この違いが、多くの「プレビューは動くのにビルドが動かない」問題の根本原因です。

問題パターン①:カスタムフォントが実機で表示されない

症状: Expo Goではカスタムフォントが適用されているのに、ビルドしたアプリではデフォルトフォントになります。

// ❌ フォントの読み込みタイミングが不適切
import * as Font from 'expo-font';
 
export default function App() {
  // フォント読み込みを待たずにレンダリングされる
  Font.loadAsync({
    'NotoSansJP': require('./assets/fonts/NotoSansJP-Regular.ttf'),
  });
  
  return <Text style={{ fontFamily: 'NotoSansJP' }}>テキスト</Text>;
}
 
// ✅ useFontsフックで読み込み完了を待つ
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect } from 'react';
 
SplashScreen.preventAutoHideAsync();
 
export default function App() {
  const [fontsLoaded, fontError] = useFonts({
    'NotoSansJP': require('./assets/fonts/NotoSansJP-Regular.ttf'),
    'NotoSansJP-Bold': require('./assets/fonts/NotoSansJP-Bold.ttf'),
  });
  
  useEffect(() => {
    if (fontsLoaded || fontError) {
      SplashScreen.hideAsync();
    }
  }, [fontsLoaded, fontError]);
  
  if (!fontsLoaded && !fontError) {
    return null; // フォント読み込み中はnullを返す
  }
  
  return <Text style={{ fontFamily: 'NotoSansJP' }}>テキスト</Text>;
}

また、app.jsonでフォントファイルをassets配列に含める必要があります。

{
  "expo": {
    "assets": [
      "./assets/fonts/NotoSansJP-Regular.ttf",
      "./assets/fonts/NotoSansJP-Bold.ttf"
    ]
  }
}

問題パターン②:ネイティブモジュールがビルド後に動かない

症状: Expo Goでは使えていた機能が、本番ビルドでのみクラッシュします。

Expo Goには組み込まれていない(またはバージョンが異なる)ネイティブモジュールを使うと、このような問題が起きます。

# まず問題のモジュールを特定する
# Expo Goと互換性がないモジュールを使っているか確認
npx expo-doctor
 
# よく問題になるモジュールの例
# - react-native-camera (Expo Go非対応 → expo-camera を使う)
# - react-native-maps (バージョン依存 → react-native-maps@1.7以降を推奨)
# - @stripe/stripe-react-native (Expo Goで制限あり → dev-clientを使う)

解決策A: Expo互換の代替モジュールに切り替える

// ❌ Expo Goで完全動作しないことがある
import { Camera } from 'react-native-camera';
 
// ✅ Expo管理のモジュールを使う
import { CameraView, useCameraPermissions } from 'expo-camera';

解決策B: Development Build(Custom Dev Client)を使う

Expo Goを使わず、カスタムのDevelopmentビルドを使うことで、本番ビルドと同じ環境でテストできます。

# EASでdevelopmentビルドを作成
eas build --profile development --platform ios
 
# または開発サーバーをdevClientモードで起動
npx expo start --dev-client

問題パターン③:環境変数がビルド後に反映されない

症状: APIエンドポイントやAPIキーが本番ビルドで参照できません。process.env.EXPO_PUBLIC_API_URLがundefinedになります。

# .env.local (Expo Goでは読み込まれるが、ビルドには反映されない場合がある)
EXPO_PUBLIC_API_URL=https://api.example.com
// ❌ 本番ビルドで環境変数が取れないケース
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
// → undefinedになることがある
 
// ✅ app.config.jsを使って確実に埋め込む
// app.config.js
export default {
  expo: {
    name: "My App",
    // 環境変数をビルド時に埋め込む
    extra: {
      apiUrl: process.env.EXPO_PUBLIC_API_URL ?? "https://api.example.com",
      apiKey: process.env.EXPO_PUBLIC_API_KEY,
    }
  }
};
// アプリ内での参照
import Constants from 'expo-constants';
 
const apiUrl = Constants.expoConfig?.extra?.apiUrl;

EAS Buildでの環境変数管理(本番環境):

// eas.json
{
  "build": {
    "production": {
      "env": {
        "EXPO_PUBLIC_API_URL": "https://api.production.example.com"
      }
    },
    "preview": {
      "env": {
        "EXPO_PUBLIC_API_URL": "https://api.staging.example.com"
      }
    }
  }
}

EAS Secretsで機密情報を安全に管理することもできます。

eas secret:create --scope project --name STRIPE_SECRET_KEY --value "sk_live_xxxx"

問題パターン④:画像やアセットがビルド後に表示されない

症状: Expo Goでは画像が表示されるのに、ビルドしたアプリで表示されない、または壊れた画像アイコンになります。

// ❌ 動的なrequireはビルドに含まれないことがある
const imagePath = `./assets/images/${imageName}.png`;
const image = require(imagePath); // ← これはビルドで機能しない
 
// ✅ 静的なrequireを使う(ビルド時にバンドルされる)
const images = {
  cat: require('./assets/images/cat.png'),
  dog: require('./assets/images/dog.png'),
  bird: require('./assets/images/bird.png'),
};
 
// 動的に選ぶ場合はオブジェクトのマッピングを使う
const image = images[imageName];

app.jsonのassets配列にも必要なアセットを追加してください。

{
  "expo": {
    "assets": ["./assets/images/", "./assets/icons/"],
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png"
    }
  }
}

デバッグの効率化:Expo Goに依存しないテスト環境の構築

長期的な解決策として、Development Buildを常用することを強くおすすめします。

# EAS CLIのインストール
npm install -g eas-cli
 
# プロジェクトの初期化
eas build:configure
 
# iOS/Android向けdevelopmentビルドの作成
eas build --profile development --platform all
 
# ビルドをインストールして起動
npx expo start --dev-client

Development Buildを使うことで、本番ビルドとほぼ同じ環境でHot Reloadを使いながら開発できます。Expo Goで動かなくなるケースを事前に発見できるため、リリース前のトラブルを大幅に減らせます。

全体を振り返って

Expo Goと実機ビルドの動作不一致は、主に以下の4パターンに分類できます。

  • カスタムフォント → useFontsフックとapp.jsonのassets配列を正しく設定する
  • ネイティブモジュール → Expo互換モジュールへの移行またはDevelopment Buildの使用
  • 環境変数 → app.config.jsextra経由またはEAS環境変数を使う
  • 動的アセット → 静的なrequireとオブジェクトマッピングに書き換える

プレビューと本番の差異を根本から解消するには、Development Buildを本開発環境として採用するのが最も効果的です。これにより、リリース後に初めてバグに気づくという状況を防げます。

本記事の内容

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-05-08
Rork Max の Cloud Compile が失敗する原因と、すぐに試せる対処法
Rork Max の Cloud Compile でビルドが失敗する時の原因を症状別に整理し、コード署名エラー・Swift バージョン不一致・タイムアウトなど、よくあるケースへの対処法を解説します。
開発ツール2026-05-05
Rork の EAS Build プロファイルを切り替えたら動かなくなった — development・preview・production の落とし穴と対処法
Rork Max の EAS Build プロファイル切り替えで起きる代表的なトラブルを解説します。environment variables の設定ミス、TestFlight への誤アップロード、production で開発用 API を叩く問題など、症状別に対処法を紹介します。
開発ツール2026-04-16
シミュレーターで動くのに実機でクラッシュ — Rork Max アプリの原因特定と修正ガイド
Rork Max で生成した SwiftUI アプリがシミュレーターでは正常動作するのに実機でクラッシュする問題を5つのパターン別に解説。クラッシュログの読み方から具体的な修正方法まで紹介します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →