React Native打包发布 #

概述 #

将 React Native 应用发布到应用商店需要经过打包、签名、上传等步骤。本章节介绍 iOS 和 Android 的打包发布流程。

iOS 打包 #

准备工作 #

  1. Apple Developer 账号
  2. App ID 配置
  3. 证书和描述文件

配置应用信息 #

ios/MyApp/Info.plist 中配置:

xml
<key>CFBundleDisplayName</key>
<string>我的应用</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>

配置签名 #

  1. 打开 Xcode
  2. 选择项目 → Signing & Capabilities
  3. 选择 Team
  4. Xcode 自动管理签名

构建发布版本 #

使用 Xcode #

bash
cd ios
pod install
  1. 打开 MyApp.xcworkspace
  2. 选择 Product → Archive
  3. 等待构建完成
  4. 点击 Distribute App
  5. 选择分发方式

使用命令行 #

bash
npx react-native build-ios --mode Release

App Store 上架 #

  1. 在 App Store Connect 创建应用
  2. 填写应用信息
  3. 上传构建版本
  4. 提交审核

Android 打包 #

生成签名密钥 #

bash
keytool -genkeypair -v -storetype PKCS12 \
  -keystore my-release-key.keystore \
  -alias my-key-alias \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000

配置签名 #

android/gradle.properties 中添加:

properties
MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****

android/app/build.gradle 中配置:

gradle
android {
  ...
  signingConfigs {
    release {
      storeFile file(MYAPP_RELEASE_STORE_FILE)
      storePassword MYAPP_RELEASE_STORE_PASSWORD
      keyAlias MYAPP_RELEASE_KEY_ALIAS
      keyPassword MYAPP_RELEASE_KEY_PASSWORD
    }
  }
  buildTypes {
    release {
      signingConfig signingConfigs.release
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
  }
}

构建发布版本 #

生成 AAB(推荐) #

bash
cd android
./gradlew bundleRelease

输出位置:android/app/build/outputs/bundle/release/app-release.aab

生成 APK #

bash
cd android
./gradlew assembleRelease

输出位置:android/app/build/outputs/apk/release/app-release.apk

Google Play 上架 #

  1. 在 Google Play Console 创建应用
  2. 填写应用信息
  3. 上传 AAB 文件
  4. 提交审核

版本管理 #

更新版本号 #

iOS #

修改 ios/MyApp/Info.plist

xml
<key>CFBundleShortVersionString</key>
<string>1.0.1</string>
<key>CFBundleVersion</key>
<string>2</string>

Android #

修改 android/app/build.gradle

gradle
android {
  defaultConfig {
    versionCode 2
    versionName "1.0.1"
  }
}

自动化版本管理 #

创建 update-version.js

javascript
const fs = require('fs');
const path = require('path');

const version = process.argv[2];
const buildNumber = process.argv[3];

// 更新 iOS
const plistPath = path.join(__dirname, 'ios/MyApp/Info.plist');
let plist = fs.readFileSync(plistPath, 'utf8');
plist = plist.replace(
  /<key>CFBundleShortVersionString<\/key>\s*<string>.*<\/string>/,
  `<key>CFBundleShortVersionString</key>\n\t<string>${version}</string>`,
);
plist = plist.replace(
  /<key>CFBundleVersion<\/key>\s*<string>.*<\/string>/,
  `<key>CFBundleVersion</key>\n\t<string>${buildNumber}</string>`,
);
fs.writeFileSync(plistPath, plist);

// 更新 Android
const gradlePath = path.join(__dirname, 'android/app/build.gradle');
let gradle = fs.readFileSync(gradlePath, 'utf8');
gradle = gradle.replace(
  /versionCode \d+/,
  `versionCode ${buildNumber}`,
);
gradle = gradle.replace(
  /versionName ".*"/,
  `versionName "${version}"`,
);
fs.writeFileSync(gradlePath, gradle);

console.log(`Version updated to ${version} (${buildNumber})`);

使用:

bash
node update-version.js 1.0.1 2

构建优化 #

Android 优化 #

android/app/build.gradle 中:

gradle
android {
  ...
  buildTypes {
    release {
      minifyEnabled true
      shrinkResources true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
  }
  
  packagingOptions {
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/NOTICE.txt'
  }
}

分架构打包 #

gradle
android {
  ...
  splits {
    abi {
      enable true
      reset()
      include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
      universalApk false
    }
  }
}

CI/CD 配置 #

GitHub Actions #

创建 .github/workflows/release.yml

yaml
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build-ios:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Install pods
        run: cd ios && pod install
      
      - name: Build iOS
        run: |
          xcodebuild -workspace ios/MyApp.xcworkspace \
            -scheme MyApp \
            -configuration Release \
            -archivePath build/MyApp.xcarchive \
            archive
      
      - name: Export IPA
        run: |
          xcodebuild -exportArchive \
            -archivePath build/MyApp.xcarchive \
            -exportPath build \
            -exportOptionsPlist ios/ExportOptions.plist

  build-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Setup Java
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '17'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build Android
        run: cd android && ./gradlew bundleRelease
      
      - name: Upload AAB
        uses: actions/upload-artifact@v3
        with:
          name: app-release
          path: android/app/build/outputs/bundle/release/app-release.aab

检查清单 #

iOS 发布检查 #

  • [ ] 更新版本号
  • [ ] 配置应用图标
  • [ ] 配置启动屏幕
  • [ ] 检查权限描述
  • [ ] 测试所有功能
  • [ ] 检查内存使用
  • [ ] 检查崩溃日志

Android 发布检查 #

  • [ ] 更新版本号
  • [ ] 配置应用图标
  • [ ] 配置签名密钥
  • [ ] 检查权限
  • [ ] 测试所有功能
  • [ ] 检查内存使用
  • [ ] 检查 ANR 日志

常见问题 #

iOS 构建失败 #

bash
# 清理构建
cd ios
rm -rf build
rm -rf Pods
pod install

Android 构建失败 #

bash
# 清理构建
cd android
./gradlew clean

签名问题 #

确保密钥文件路径正确,密码正确。

总结 #

打包发布要点:

  • iOS:使用 Xcode Archive
  • Android:使用 Gradle 构建
  • 签名:配置正确的签名
  • 版本管理:统一管理版本号
  • CI/CD:自动化构建流程

继续学习 热更新,了解如何实现应用热更新。

最后更新:2026-03-28