要将 Capacitor 应用升级到 Capacitor 8,请安装 Node.js 22+、Xcode 26+ 和 Android Studio Otter,并更新 @capacitor/cli 至最新的 8.x 版本,运行 bunx cap migrate,然后修复迁移工具报告的问题。主要破坏性变更包括:iOS 最低部署目标为 15,Android SDK 36(minSdk 24),AGP 8.13 配合 Gradle 8.14.3,以及移除 adjustMarginsForEdgeToEdge ,改用新的 System Bars 插件。
本指南将介绍自动化路径、其背后的每个手动步骤,以及升级后最常遇到的错误。如果您维护的是插件而非应用,请阅读 如何将您的 Capacitor 插件升级到 Capacitor 8 请改用这种方式。
Capacitor 8 项要求一览
在接触项目之前,请先检查您的工具链。大多数升级失败是由于 CI 中的旧版 JDK、旧版 Xcode 或旧版 Node 造成的,而不是 code 本身的问题。
| 领域 | Capacitor 7 | Capacitor 8 |
|---|---|---|
| Node.js | 20+ | 22+(CLI 声明 engines.node >= 22.0.0) |
| Xcode 的 Mac | 16+ | 26+ |
| iOS 部署目标 | 14.0 | 15.0 |
| Android Studio 中的错误日志 | Ladybug | Otter 2025.2.1+ |
| minSdkVersion | 23 | 24 |
| compileSdkVersion / targetSdkVersion | 35 | 36 |
| Android Gradle 插件 | 8.7.2 | 8.13.0 |
| Gradle wrapper | 8.11.1 | 8.14.3 |
| Kotlin(如使用) | 1.9.25 | 2.2.20 |
| Android 构建所需的 JDK | 21 | 21 (@capacitor/android 使用 Java 21 编译) |
| 全新的 iOS 平台默认配置 | CocoaPods | Swift Package Manager |
Xcode 26 不仅仅是 Capacitor 的要求。自 2026 年 4 月 28 日起,App Store Connect 会拒绝使用旧版 Xcode 构建的上传包,所以你无论如何都需要它。请参阅 Apple 对 Capacitor 应用的 Xcode 26 要求 了解详情。
开始之前
- 请先提交所有更改,或创建一个新分支。迁移工具会就地修改原生文件。
- 请确保你的 App 目前能在 Capacitor 7 上正常构建。在已经坏掉的项目上做升级只会增加噪音。
- 如果你使用的是 Capacitor 6 或更早版本,请先完成上一个大版本的升级。每个大版本在 CLI 中都有各自的迁移逻辑。
- 使用以下命令列出你的插件:
bunx cap ls并检查每个插件是否都有支持 Capacitor 8 的发布版本。请查看peerDependencies的最新版本:
bun pm view @capgo/capacitor-updater peerDependencies
一个包含 @capacitor/core: ^7.0.0 作为其 peer 的插件在安装时会发出警告,并可能导致编译失败。Capgo 插件在其自身版本号中遵循 Capacitor 的主版本,因此 @capgo/* 8.x 版本针对 Capacitor 8。
- 更新本地和 CI 工具链:Node 22、Xcode 26、JDK 21、Android Studio Otter。在 GitHub Actions 中,固定一个附带 Xcode 26 的 macOS 镜像,并使用
actions/setup-java配合java-version: '21'.
选项 1:使用 cap migrate
CLI 内置了迁移命令,可自动处理大部分工作。安装最新版本的 CLI,然后运行:
bun add -D @capacitor/cli@latest
bunx cap migrate
The migrator asks whether it should install the new Capacitor packages and lets you pick npm, Yarn, pnpm or Bun. Pick Bun if your project has a bun.lock。你可以跳过该提示 bunx cap migrate --noprompt.
跳过该提示。
- 它为你做了以下更改:
@capacitor/core,@capacitor/ios,@capacitor/android将@capacitor/*和官方 - 集合
IPHONEOS_DEPLOYMENT_TARGET = 15.0插件升级到 8.x。platform :ios, '15.0'在 Xcode 项目中更新 - 更新
variables.gradle,在 Podfile 中更新kotlin_version. - 新增
density改为android:configChanges中的AndroidManifest.xml.
阅读完整输出。如果某一步无法应用(例如因为文件已被自定义),CLI 会打印包含文件名的错误并继续执行。这些行就是你的手动待办清单。
完成后:
bun run build
bunx cap sync
然后打开每个平台,从 IDE 构建一次,以便完整查看原生错误。
选项 2:手动升级
如果你的原生项目经过大量自定义,或者迁移工具跳过了某些步骤,请手动应用更改。这些更改对应于 官方 Capacitor 8 升级指南.
更新 npm 包
bun add @capacitor/core@latest @capacitor/ios@latest @capacitor/android@latest
bun add -D @capacitor/cli@latest
然后更新每个官方插件,例如:
bun add @capacitor/app@latest @capacitor/splash-screen@latest @capacitor/status-bar@latest
iOS:将部署目标提升至 15.0
在 Xcode 中,选择项目,打开 Build Settings 中调高部署目标,找到 iOS 部署目标 在……下 部署 并将其设置为 15.0。对包括扩展在内的每个 app target 重复此操作。
如果 app 仍在使用 CocoaPods,请更新 ios/App/Podfile:
platform :ios, '15.0'
然后运行 bunx cap sync ios,它会运行 pod install 来为你完成操作。
如果 app 使用 SPM,CLI 会重新生成 ios/App/CapApp-SPM/Package.swift 在每次同步时,使用正确的平台版本和精确的 capacitor-swift-pm 版本,该版本与你安装的 @capacitor/ios相匹配。请勿手动编辑该文件。
iOS:移除自定义 view controller 通知
Capacitor 8 现在会发出 CAPBridgeViewController 的通知 viewDidAppear 以及 viewWillTransition 本身。如果你添加了扩展或子类来发送 .capacitorViewDidAppear 或 .capacitorViewWillTransition,请将其删除,否则监听器会触发两次。
Android:更新 Android Studio 和 AGP
安装 Android Studio Otter 或更高版本,打开 android 文件夹并运行 工具 > AGP 升级助手。选择 8.13.0 并运行所选步骤。或者编辑 android/build.gradle 直接:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.13.0'
classpath 'com.google.gms:google-services:4.4.4'
}
}
并且 android/gradle/wrapper/gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
Android:更新 variables.gradle
ext {
minSdkVersion = 24
compileSdkVersion = 36
targetSdkVersion = 36
androidxActivityVersion = '1.11.0'
androidxAppCompatVersion = '1.7.1'
androidxCoordinatorLayoutVersion = '1.3.0'
androidxCoreVersion = '1.17.0'
androidxFragmentVersion = '1.8.9'
coreSplashScreenVersion = '1.2.0'
androidxWebkitVersion = '1.14.0'
junitVersion = '4.13.2'
androidxJunitVersion = '1.3.0'
androidxEspressoCoreVersion = '3.7.0'
cordovaAndroidVersion = '14.0.1'
}
保留插件读取的额外变量(例如 firebaseMessagingVersion)。Capacitor 8 的官方插件版本升级包括 firebaseMessagingVersion = '25.0.1', androidxBrowserVersion = '1.9.0', androidxMaterialVersion = '1.13.0' 以及 androidxExifInterfaceVersion = '1.4.1'.
Android:切换到 = Gradle 文件中的赋值
Gradle 已弃用空格赋值语法。目前仅会发出警告,但将在未来的 Gradle 版本中导致错误,因此请在以下位置立即修复: android/app/build.gradle:
android {
- namespace "com.example.app"
- compileSdk rootProject.ext.compileSdkVersion
+ namespace = "com.example.app"
+ compileSdk = rootProject.ext.compileSdkVersion
defaultConfig {
aaptOptions {
- ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
+ ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}
}
诸如 google() 或 mavenCentral() 这样的方法调用保持不变。
Android:Kotlin 和 configChanges
如果你的 app 模块使用 Kotlin,请设置 kotlin_version = '2.2.20'。Kotlin 2.x 会把旧的 kotlinOptions {} 块变成错误,因此请移动 jvmTarget 为 kotlin { compilerOptions { ... } }.
然后添加 density 到主 Activity 中,这样显示密度变化时(折叠屏、窗口大小调整、显示大小设置)WebView 就不会被重新创建:
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation|density"
Android:桥接布局已重命名,
bridge_layout_main.xml 已不存在。如果你的 MainActivity 或自定义引用的片段 R.layout.bridge_layout_main,使用 R.layout.capacitor_bridge_layout_main.
Edge-to-edge 与新的 System Bars 插件
这是最可能在视觉上显现的变化。Capacitor 8 移除了 android.adjustMarginsForEdgeToEdge 并新增了核心 System Bars 插件。你无需安装它,它随 @capacitor/core.
Android 15 对 targetSdk 为 SDK 35 的应用强制启用 edge-to-edge,Android 16 则移除了 targetSdk 为 SDK 36 的应用的退出选项。Capacitor 8 的 targetSdk 为 36,因此除非你处理 insets,否则 web 内容现在会绘制到状态栏和导航栏后面。
插件配置位于 plugins.SystemBars:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example',
webDir: 'dist',
plugins: {
SystemBars: {
// 'css' (default) injects --safe-area-inset-* variables on Android
// 'native' relies on env() and viewport-fit
// 'disable' leaves inset handling entirely to you
insetsHandling: 'css',
initialViewportFitValueHint: 'cover',
},
},
};
export default config;
使用 css 或 native,较新的 Android WebViews (Chromium 140+) 会遵循 viewport-fit=cover 并报告真实的 env(safe-area-inset-*) 值。在旧版 WebView 上,Capacitor 会为 WebView 加 padding,并将 env 值设为 0px。因此,请设置 meta 标签并使用这些变量:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
}
在运行时,你可以更改状态栏样式或可见性:
import { SystemBars, SystemBarsStyle, SystemBarType } from '@capacitor/core';
await SystemBars.setStyle({ style: SystemBarsStyle.Dark });
await SystemBars.hide({ bar: SystemBarType.NavigationBar });
Ionic Framework 应用已经在使用 safe-area 变量,因此通常只需要设置 meta 标签。我们之前关于 不用插件实现 edge-to-edge 的文章介绍了 Capacitor 7 的选项,该选项在 8 中已不再存在。
其他需要检查的行为变更
appendUserAgent在 iOS 上:Capacitor 7 会在字符串前添加两个空格,Capacitor 8 则添加一个。如果你的服务器严格解析 User Agent,请在开头添加一个空格ios.appendUserAgent(而非根选项,后者也会影响 Android)。- 屏幕方向与条码扫描器:在 Android 16+ 的大屏设备上,方向锁定会被忽略。目前可通过
android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITYmanifest 属性临时禁用,但 Android 17 将移除该功能。 - 地理位置:
timeout现在适用于 Android 和 iOS 上的所有请求。如果出现新的超时,请调高该值。watchPosition在 Android 上新增了一个interval选项。 - 状态栏:该插件不再自带
CAPBridgeViewController通知文件,因为 core 现在会发出这些事件。 - 新建 iOS 平台默认使用 SPM:
bunx cap add ios现在会创建一个 SPM 项目。使用--packagemanager CocoaPods如需旧模板。参见 如何在 Capacitor 8 中使用 CocoaPods.
验证升级
发布前,请在两个平台上逐项检查:
bunx cap doctor
bunx cap sync
bunx cap run ios
bunx cap run android
cap doctor显示 core、CLI、iOS 和 Android 对应的 8.x 版本。- 应用正常启动,启动页正确隐藏,深度链接打开正确的页面。
- 状态栏和导航栏区域在 Android 15/16 设备以及带刘海的 iPhone 上显示正常。
- 推送通知、相机、文件访问以及任何需要原生权限的插件仍能正常工作。
- Release 构建(在 Xcode 中 Archive
./gradlew bundleRelease)能成功,而不只是 debug。
如果你不想在每台机器上都维护 Xcode 26 和 JDK 21, Capgo 构建 可以用当前工具链在云端运行 iOS 和 Android 构建。
通过 Live Updates 安全地发布升级
一次 Capacitor 大版本升级会改动原生 code,因此必须走 App Store 和 Google Play。升级后构建的 web bundle 可能会调用旧版二进制没有的插件 API。
如果你使用 Capgo 实时更新,请在采用率跟上之前,将 Capacitor 7 用户与 Capacitor 8 用户隔开:提升原生版本号,把新 bundle 上传到新二进制使用的 channel,然后运行 兼容性检查 后再上传:
bunx @capgo/cli@latest bundle compatibility
它会比较 bundle 中的原生插件版本与 channel 上正在运行的版本,并在用户收到损坏的更新之前标记出不匹配项。
常见 Capacitor 8 升级错误排查
The engine "node" is incompatible 或者 CLI 拒绝运行。 你正在使用 Node 20 或更早版本。请安装 Node 22 LTS,并更新你的 CI 镜像。
error: invalid source release: 21 在 Android 上。 Gradle 正在用 JDK 17 运行。请把 Android Studio 指向它自带的 JDK 21 (Settings > Build, Execution, Deployment > Build Tools > Gradle > Gradle JDK) 并设置 JAVA_HOME 到 JDK 21,用于命令行和 CI 构建。
Minimum supported Gradle version is 8.13. 你更新了 AGP,但没有更新 wrapper。请将 wrapper 设置为 8.14.3。
Dependency ... requires libraries and applications that depend on it to compile against version 36. compileSdkVersion 某处仍然是 35。请检查 variables.gradle 以及任何硬编码该值的插件。
Using 'kotlinOptions' ... is an error 或类似的 Kotlin DSL 错误。某个插件或你的 app 模块仍在使用 kotlinOptions。请更新该插件,或在正式发布前进行补丁修复(参见 如何为 Capacitor 插件打补丁).
Xcode: No such module 'Capacitor' 升级后。 对于 CocoaPods,请打开 App.xcworkspace,而不是 App.xcodeproj,然后重新运行 bunx cap sync ios。对于 SPM,请使用 File > Packages > Reset Package Caches.
"X" plugin is not implemented on ios/android. 插件未同步,或没有兼容 Capacitor 8 / SPM 的版本。请运行 bunx cap sync 并查看警告信息。
如需查看更详细的列表,请参阅 Capacitor iOS 故障排除指南 以及 Android 故障排除指南。核心与插件版本不匹配的问题,请参阅 修复 Capacitor 版本不匹配错误.
让 AI Agent 处理枯燥的任务
如果你使用 Claude Code、Cursor 或类似的智能体,打开 Capgo 技能 包括 capacitor-app-upgrade-v7-to-v8 以及 capacitor-app-upgrades 以支持跨多个主版本的升级。使用以下命令安装: bunx skills add Cap-go/capgo-skills 并让 agent 升级应用。它会运行 migrator,然后检查 CLI 通常会漏掉的步骤,比如 Gradle 语法、Kotlin 选项和 CI 镜像。
后续步骤
Capacitor 9 已进入预发布阶段。当你在 8 上稳定后,请阅读 为 Capacitor 9 做准备 这样下次升级的改动会更小。