You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建React Native免费与付费版本的统一仓库及工作流

Hey there! Great question—maintaining two separate React Native apps for free and paid versions is a total slog, so let’s break down a clean repo structure and workflow that keeps you from duplicating work while supporting both variants.

1. Repo Structure: One Codebase, Two Variants

Forget separate repos—keep all your code in a single repository with a clear split between shared and version-specific code. Here’s a practical setup:

your-app/
├── src/
│   ├── common/          # All shared code: UI components, core logic, API calls
│   ├── free/            # Free-only features (ads, limited functionality prompts)
│   ├── paid/            # Paid-only premium features
│   ├── App.js           # Entry point that loads variant-specific modules
│   └── config/          # Variant configs (API keys, feature flags)
├── android/
│   ├── app/
│   │   ├── src/
│   │   │   ├── main/    # Shared Android setup
│   │   │   ├── free/    # Free variant config (Play Store ID, ad SDK setup)
│   │   │   └── paid/    # Paid variant config (no ads, premium entitlements)
│   └── build.gradle     # Configure Android product flavors
├── ios/
│   ├── YourApp/
│   │   ├── Common/      # Shared iOS code
│   │   ├── Free/        # Free variant settings
│   │   └── Paid/        # Paid variant settings
│   └── YourApp.xcodeproj # Set up iOS targets for each variant
└── .env                 # Environment variables to flag FREE/PAID builds
2. Feature Differentiation: Keep It Clean

The key is to use environment variables and platform-specific build configurations to toggle features without messy code duplication.

  • React Native Code Checks
    Use an environment variable to branch logic in your JS/TS code:

    const isPaidVersion = process.env.APP_VARIANT === 'PAID';
    
    // Example component
    function PremiumDashboard() {
      if (!isPaidVersion) {
        return <UpgradeToProPrompt />;
      }
      return <ActualPremiumDashboard />;
    }
    

    For larger premium features, use dynamic imports to keep free app bundle size small:

    let PremiumModule;
    if (isPaidVersion) {
      PremiumModule = require('../paid/PremiumModule').default;
    } else {
      PremiumModule = require('../free/UpgradeModule').default;
    }
    
  • Android Product Flavors
    In android/app/build.gradle, define flavors to generate separate APKs with unique IDs and settings:

    android {
      flavorDimensions "version"
      productFlavors {
        free {
          dimension "version"
          applicationId "com.yourapp.free"
          resValue "string", "app_name", "Your App"
        }
        paid {
          dimension "version"
          applicationId "com.yourapp.paid"
          resValue "string", "app_name", "Your App Pro"
        }
      }
    }
    
  • iOS Targets
    Duplicate your main iOS target in Xcode, name it YourAppPaid, and update its Bundle ID, display name, and entitlements. Use preprocessor macros to branch native code:

    #ifdef PAID_VERSION
      // Paid-only native logic (e.g., remove ad SDK hooks)
    #else
      // Free-only native logic
    #endif
    
3. Build & Release Workflow: Automate Everything

Manual builds for two variants are error-prone—automate the process to save time.

  • Package Scripts
    Add these to your package.json to trigger variant-specific builds:

    "scripts": {
      "build:free:android": "APP_VARIANT=FREE cd android && ./gradlew assembleFreeRelease",
      "build:paid:android": "APP_VARIANT=PAID cd android && ./gradlew assemblePaidRelease",
      "build:free:ios": "APP_VARIANT=FREE xcodebuild -workspace ios/YourApp.xcworkspace -scheme YourAppFree -configuration Release archive",
      "build:paid:ios": "APP_VARIANT=PAID xcodebuild -workspace ios/YourApp.xcworkspace -scheme YourAppPaid -configuration Release archive"
    }
    
  • CI/CD Integration
    Set up pipelines (GitHub Actions, GitLab CI, etc.) to automatically build both variants on every main branch push. Configure them to upload builds directly to Play Store/App Store Connect’s testing tracks for easy validation.

  • Sync Version Numbers
    Keep version codes and names in sync across variants. Manage the core version in package.json, then reference it in your Android build.gradle and iOS Info.plist to avoid mismatches.

4. Pro Tips for Long-Term Maintainability
  • Keep Shared Code Pure: Avoid cluttering common code with variant-specific conditionals. Encapsulate variant logic in free/paid modules and expose consistent interfaces to shared code.
  • Test Both Variants: Use your test framework’s environment variable support (e.g., Jest’s setupFiles) to run tests for both free and paid scenarios.
  • Link Apps in Stores: In Play Console, mark your free and paid apps as "related" so users can easily upgrade from the free version’s store listing.

内容的提问来源于stack exchange,提问作者Aswin Mohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:00:00