react navite 安卓iOS 打包、签名、环境区分

27 阅读3分钟

如果你现在是在做 React Native 原生 Android + iOS 项目,可以把「打包、签名、环境区分」理解成三件事:

开发环境 → 测试环境 → 生产环境
↓
不同配置 → 不同包名/Bundle ID → 不同签名 → 不同安装包

我给你按实际项目中比较常用的方案梳理一下。


一、推荐的环境划分

建议至少分:

环境AndroidiOS用途
dev开发包开发包本地开发
test测试包测试包测试/联调
prod正式包正式包上架

例如:

开发环境
com.example.app.dev

测试环境
com.example.app.test

生产环境
com.example.app

这样三个 App 可以同时安装在手机上,非常方便。


二、React Native 环境变量

推荐使用:

react-native-config

例如:

.env
.env.development
.env.test
.env.production

.env.development

API_URL=https://dev-api.example.com
APP_ENV=development

.env.test

API_URL=https://test-api.example.com
APP_ENV=test

.env.production

API_URL=https://api.example.com
APP_ENV=production

JS 中:

import Config from 'react-native-config';

console.log(Config.API_URL);
console.log(Config.APP_ENV);

例如:

fetch(`${Config.API_URL}/user/info`);

三、Android 打包

Android 原生项目:

android/
├── app/
│   ├── build.gradle
│   └── ...
└── build.gradle

Android 最常见的环境方案是:

productFlavors

例如:

android {
    ...

    flavorDimensions "environment"

    productFlavors {
        dev {
            dimension "environment"
            applicationIdSuffix ".dev"
            versionNameSuffix "-dev"
        }

        test {
            dimension "environment"
            applicationIdSuffix ".test"
            versionNameSuffix "-test"
        }

        prod {
            dimension "environment"
        }
    }
}

最终:

dev
com.example.app.dev

test
com.example.app.test

prod
com.example.app

四、Android 签名

正式 Android 包一定需要签名。

通常:

release.keystore

例如生成:

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

然后:

android/app/release.keystore

不要把 keystore 提交到 Git。

推荐:

android/gradle.properties

配置:

MYAPP_UPLOAD_STORE_FILE=release.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key
MYAPP_UPLOAD_STORE_PASSWORD=******
MYAPP_UPLOAD_KEY_PASSWORD=******

更推荐生产环境通过:

CI/CD Secret

注入,而不是直接写进项目。


五、Android Release 签名配置

android/app/build.gradle:

android {

    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release

            minifyEnabled false
            shrinkResources false
        }
    }
}

然后执行:

cd android

正式 APK:

./gradlew assembleProdRelease

Windows:

gradlew.bat assembleProdRelease

生成:

android/app/build/outputs/apk/release/

如果使用 AAB:

gradlew.bat bundleProdRelease

生成:

app-prod-release.aab

Google Play 推荐上传 AAB。


六、Android Debug / Test / Production

最终可以形成:

# 开发
npx react-native run-android --mode devDebug

# 测试
cd android
gradlew.bat assembleTestRelease

# 正式
gradlew.bat bundleProdRelease

也可以:

gradlew.bat assembleDevDebug
gradlew.bat assembleTestRelease
gradlew.bat assembleProdRelease

七、iOS 环境区分

iOS 比 Android 稍微麻烦一些。

通常使用:

Scheme
+
Build Configuration
+
xcconfig

例如:

Debug-Dev
Debug-Test
Release-Dev
Release-Test
Release-Prod

或者简单一点:

Dev
Test
Prod

八、iOS Bundle Identifier

例如:

Development
com.example.app.dev

Test
com.example.app.test

Production
com.example.app

这样可以:

App Dev
App Test
App

同时安装。

这是非常推荐的方案。


九、iOS Signing

iOS 签名涉及:

Apple Developer
    ↓
Certificate
    ↓
Provisioning Profile
    ↓
Bundle Identifier

生产环境一般:

Apple Distribution Certificate
+
App Store Provisioning Profile

测试环境可以:

Apple Development

或者:

Ad Hoc

如果是公司项目,我更推荐使用:

Xcode Automatic Signing

开发阶段。

生产 CI/CD 再使用:

Match

管理证书和 Provisioning Profile。


十、iOS Scheme

例如:

App
App-Dev
App-Test

Scheme:

App-Dev
    ↓
Debug-Dev

App-Test
    ↓
Debug-Test

App
    ↓
Release-Prod

然后不同 Scheme 使用不同:

.xcconfig

例如:

Config/
├── Dev.xcconfig
├── Test.xcconfig
└── Prod.xcconfig

十一、iOS xcconfig

Dev.xcconfig

API_URL = https://dev-api.example.com
APP_ENV = development

Test.xcconfig

API_URL = https://test-api.example.com
APP_ENV = test

Prod.xcconfig

API_URL = https://api.example.com
APP_ENV = production

然后让:

Dev Scheme → Dev.xcconfig
Test Scheme → Test.xcconfig
Prod Scheme → Prod.xcconfig

十二、RN 项目最终结构

我比较推荐你做成这样:

ReactNativeProject
│
├── src/
│   ├── api/
│   ├── components/
│   ├── screens/
│   └── config/
│
├── .env.development
├── .env.test
├── .env.production
│
├── android/
│   └── app/
│       ├── build.gradle
│       └── src/
│           ├── dev/
│           ├── test/
│           └── prod/
│
└── ios/
    ├── App/
    ├── Config/
    │   ├── Dev.xcconfig
    │   ├── Test.xcconfig
    │   └── Prod.xcconfig
    │
    └── ...

十三、最重要:不要只区分 API

很多 RN 项目一开始只做:

API_URL=xxx

实际上生产项目最好同时区分:

API 地址
App 名称
Bundle ID
Android applicationId
推送 AppKey
地图 Key
微信 AppID
支付宝 AppID
Firebase
Google Service
Sentry
统计 SDK

例如:

Dev

com.example.app.dev
https://dev-api.example.com
Firebase Dev
Sentry Dev
微信 Dev


Test

com.example.app.test
https://test-api.example.com
Firebase Test
Sentry Test


Prod

com.example.app
https://api.example.com
Firebase Prod
Sentry Prod
微信 Prod

十四、推荐的完整发布流程

实际公司项目可以这样:

                    Git
                     │
          ┌──────────┼──────────┐
          ↓          ↓          ↓
         Dev        Test       Prod
          │          │          │
          ↓          ↓          ↓
       Debug APK   APK/AAB    AAB
          │          │          │
          ↓          ↓          ↓
       开发人员     测试人员    App Store
                              Google Play

更进一步:

Git Push
   ↓
GitHub Actions
   ↓
┌───────────────┐
│ Environment   │
├───────────────┤
│ dev           │
│ test          │
│ production    │
└───────────────┘
   ↓
Android Build + Sign
   +
iOS Build + Sign
   ↓
Artifact
   ↓
TestFlight / Google Play

十五、如果你现在刚开始做 RN 项目

我建议你不要一开始搞得特别复杂。

直接采用:

React Native
│
├── .env.development
├── .env.test
├── .env.production
│
├── Android
│   ├── dev
│   ├── test
│   └── prod
│
└── iOS
    ├── Dev Scheme
    ├── Test Scheme
    └── Prod Scheme

核心对应关系:

              Android                  iOS
──────────────────────────────────────────────
开发          devDebug                 Dev
测试          testRelease              Test
生产          prodRelease              Prod
──────────────────────────────────────────────
包名          applicationId            Bundle ID
签名          keystore                 Certificate
环境变量      .env                     xcconfig
发布          APK/AAB                  IPA/TestFlight

**如果你是准备做一个真正能上线的 RN 项目,我建议下一步直接把「Android productFlavors + iOS Scheme + .env + 签名 + GitHub Actions CI/CD」一次性搭起来。**这样以后你执行类似 npm run android:test、npm run ios:dev、npm run build:prod 就能自动走对应环境。