在本教程中,我们将从头开始创建一个新的 React app and transition to native mobile development using Capacitor. You can also add Capgo Native Navigation and Transitions for a native mobile feel, and use tailwind-capacitor for safe areas.
Capacitor 可以让您轻松将 React 网页应用转换为原生移动应用,无需进行重大修改或学习新的技能,如 React Native。
使用几步简单的步骤,大多数React应用程序可以转化为移动应用。
本教程将指导您完成整个过程,首先使用新 React 应用程序,然后将其与 Capacitor 结合起来,进入原生移动应用的领域。您还可以使用 Capgo 原生导航、过渡和 tailwind-capacitor 安全区域。
About Capacitor
CapacitorJS 是一个革命性的工具!您可以轻松将其整合到任何 Web 项目中,它会将您的应用程序包装在一个原生 Webview 中,并为您生成 Xcode 和 Android Studio 项目。另外,它的插件可以通过 JS 桥提供对原生设备功能的访问,如摄像头。
With Capacitor, you get a fantastic native mobile app without any complicated setup or steep learning curve. Its slim API and streamlined functionality make it a breeze to integrate into your project. Trust me, you’ll be amazed at how effortless it is to achieve a fully functional native app with Capacitor!
准备您的 React 应用
在本教程中,我们将使用最简单的方法来启动React应用,提供一个空白的React应用。
npx create-react-app my-app
为了创建一个原生移动应用,我们需要一个 export 项目的 。因此,让我们在我们的 package.json
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
中添加一个简单的脚本,用于构建和导出React项目: npm run build 您现在可以无忧无虑地
This folder will be used by Capacitor later on, but for now, we must set it up correctly.
在您的 React 应用中添加 Capacitor
使用,但现在我们必须正确设置它。 sync 命令。
首先,我们可以安装 Capacitor CLI 作为开发依赖项,并在项目中设置它。在设置过程中,您可以按“回车”键接受默认值的名称和包ID。
接下来,我们需要安装核心包和iOS和Android平台的相关包。
最后,我们可以添加平台,Capacitor 将在项目根目录创建每个平台的文件夹:
# Install the Capacitor CLI locally
npm install -D @capacitor/cli
# Initialize Capacitor in your React project
npx cap init
# Install the required packages
npm install @capacitor/core @capacitor/ios @capacitor/android
# Add the native platforms
npx cap add ios
npx cap add android
到目前为止,您应该能够观察到新的 ios 和 context android
context
为了以后访问 Android 项目,您必须安装 安卓 studio.对于 iOS,您需要一台 Mac,并应安装 Xcode.
另外,您应该找到一个 capacitor.config.ts 文件在您的项目中,该文件包含一些基本的Capacitor设置,在同步过程中使用。您需要注意的是 webDir,它必须指向您的构建命令的结果。目前,它是不准确的。
为了纠正这个问题,请打开 capacitor.config.json 文件并更新 webDir:
{
"appId": "com.example.app",
"appName": "my-app",
"webDir": "out",
"bundledWebRuntime": false
}
您可以通过执行以下命令来尝试它:
npm run build
npx cap sync
第一个命令 npm run build 将仅构建您的React项目并导出静态构建。
而第二个命令 npx cap sync 将同步所有的web code 到native平台的正确位置,以便在app中显示。
此外,同步命令可能会更新native平台并安装插件,因此当您安装新的 Capacitor 插件 npx cap sync 时
它的时间
重新运行它。
为了开发iOS应用,您需要安装 Xcode 并且对于Android应用,您需要安装 安卓 Studio 此外,如果您计划将应用发布到应用商店,则需要为iOS和Android分别加入Apple Developer Program和Google Play Console。
如果您是native移动开发的新手,可以使用Capacitor CLI轻松打开两个native项目:
npx cap open ios
npx cap open android
一旦您设置好了native项目,部署应用到连接设备就很容易了。在Android Studio中,只需等待所有内容就绪,然后您可以在不更改任何设置的情况下将应用部署到连接设备。以下是一个示例:

在Xcode中,您需要设置您的签名账户才能将应用部署到真实设备,而不是仅仅在模拟器上。 如果您之前没有这样做过,Xcode会指导您完成这个过程(但请再次注意,您需要加入开发者计划)。 之后,您只需点击播放即可在连接设备上运行应用,您可以在顶部选择设备。以下是一个示例:

恭喜!您成功将React web应用部署到移动设备。以下是一个示例:
但是,在开发过程中,还有更快的方法……
Capacitor 实时重载
到目前为止,您可能习惯于使用所有现代框架的热重载功能,好消息是您可以轻松获得相同的功能 在移动设备上 !
启用对您的本地托管应用程序的实时重载 在您的网络上 通过让Capacitor应用程序从特定URL加载内容
第一步是确定您的本地IP地址。如果您使用Mac,可以通过在终端中运行以下命令来查找此信息:
ipconfig getifaddr en0
在Windows上运行:
ipconfig
然后查找IPv4地址
我们可以通过在配置文件中添加另一个条目来指示Capacitor从服务器直接加载应用程序: capacitor.config.ts file:
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'out',
bundledWebRuntime: false,
server: {
url: 'http://192.168.x.xx:3000',
cleartext: true
}
};
export default config;
请确保使用 正确的IP和端口,我在本例中使用了默认的React端口。
现在,我们可以将这些更改应用到我们的原生项目中:
npx cap copy
命令与 copy 类似,但它只会 sync将对web文件夹和配置的更改复制到原生项目中,而不更新原生项目。 您现在可以通过Android Studio或Xcode再次部署您的应用。之后,如果您在React应用中更改了什么 应用将自动重新加载
file: 请确保使用正确的IP和端口 并显示更改!
请注意 如果您安装了新插件,如摄像头插件,它仍然需要重建您的原生项目。这是因为原生文件已更改,无法在飞行中完成。
请注意,您应该在配置中使用正确的IP和端口。上面的code块显示了示例目的地端口。
使用Capacitor插件
让我们看看如何使用Capacitor插件的示例,之前我们提到过几次。要实现这一点,我们可以通过运行以下命令安装一个相当简单的插件:
npm i @capacitor/share
没有什么特别的关于 分享插件,但它仍然会弹出原生分享对话框!现在我们只需要导入包并从我们的应用程序中调用 share() 函数。让我们将 src/App.js 修改为如下内容:
import React from 'react';
import { Share } from '@capacitor/share';
function App() {
const share = async () => {
await Share.share({
title: 'Open Youtube',
text: 'Check new video on youtube',
url: 'https://www.youtube.com',
dialogTitle: 'Share with friends'
});
};
return (
<div>
<h1>Welcome to React and Capacitor!</h1>
<p>
<h2>Cool channel</h2>
<button onClick={() => share()}>Share now!</button>
</p>
</div>
);
}
export default App;
如前所述,当安装新插件时,我们需要执行同步操作,然后重新部署应用到设备上。要执行此操作,请运行以下命令:
npx cap sync
点击按钮后,您可以亲眼目睹美丽的原生分享对话框!
接下来,您可以使应用在iOS和Android上感觉更原生,使用Capgo导航和过渡,并修复常见的iOS布局问题,导致水平溢出或安全区域裁剪。
原生感知UI与Capgo原生导航和过渡
我已经工作了几年, Ionic 来构建跨平台应用,但将其与React集成起来很hacky,并且很少值得一试,因为您已经有 Tailwind CSS.
在一个React + Capacitor应用中,使用Capgo插件来实现原生移动感受,而不是像Konsta UI这样的仅限Web UI套件:
- @capgo/capacitor-原生导航 —原生导航栏,Liquid Glass iOS标签栏,Android模糊标签栏样式。您的React路由器保留路由状态;插件拥有原生浏览器。
- @capgo/capacitor-过渡 — Ionic-style页面过渡和iOS边缘滑动返回在WebView层,未采用Ionic UI。
安装双方:
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
配置本机导航以CSS inset模式,使Web内容尊严本机栏:
import { NativeNavigation } from '@capgo/capacitor-native-navigation';
await NativeNavigation.configure({
contentInsetMode: 'css',
animationDuration: 360,
glass: {
effect: 'liquidGlass',
},
});
渲染液态玻璃标签栏(iOS使用系统所有的渲染;Android使用模糊的WebView背景):
await NativeNavigation.setTabbar({
selectedId: 'home',
labelVisibilityMode: 'labeled',
icons: true,
colors: { dynamic: true },
tabs: [
{ id: 'home', title: 'Home', icon: { svg: '...' } },
{ id: 'settings', title: 'Settings', icon: { svg: '...' } },
],
});
await NativeNavigation.addListener('tabSelect', ({ id }) => {
navigate(`/${id}`);
});
在应用壳中添加本机页面过渡:
import { useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';
initTransitions({ platform: 'auto' });
export function AppShell() {
const navigate = useNavigate();
const outletRef = useRef<HTMLElement>(null);
useEffect(() => {
if (outletRef.current) {
setupRouterOutlet(outletRef.current, { platform: 'auto', swipeGesture: 'auto' });
}
}, []);
const openSettings = () => {
setDirection('forward');
navigate('/settings');
};
return <cap-router-outlet ref={outletRef}>{/* routes */}</cap-router-outlet>;
}
在应用中包裹 cap-router-outlet, cap-page, 和 cap-content, 并调用 setDirection('forward') 或 setDirection('back') 参见完整指南:
context 使用@capgo/capacitor-原生导航 and 使用@capgo/capacitor-过渡.
安全区域使用Tailwind
在Tailwind CSS中,使用设备安全区域 使用@capgo/tailwind-capacitor (发布于 tailwind-capacitor npm) safe-areas utilities 和其他 Capacitor 兼容的 Tailwind 插件
bun add -D tailwind-capacitor
In src/index.css:
@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";
在 pt-safe, pb-safe使用工具,如 px-safe 取代手动添加 env(safe-area-inset-*) 为您的 React 设置而开发中 — 如果某些内容缺失, 在 GitHub 上打开一个 PR.
修复 iOS 布局问题(视口、安全区域和水平溢出)
如果 iOS 内容被裁切、偏移或水平滚动, overflow-x: hidden 添加或调整视口标签通常无法解决问题。按照以下顺序检查这些内容。
确保视口元标签正确应用
在 index.html 添加视口元标签 <head>:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
在
处理 iOS 安全区域
html,
body,
#root {
width: 100%;
min-height: 100%;
margin: 0;
padding: 0;
overflow-x: hidden;
}
* {
box-sizing: border-box;
}
.app-shell {
min-height: 100dvh;
width: 100%;
padding-top: env(safe-area-inset-top);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
}
创建一个单一的应用 shell 并在其中应用安全区域填充 — 不要在多个嵌套组件中进行: .app-shell . 在头部、模态窗口和布局包装器中重复使用安全区域填充,通常会使 UI 看起来被裁剪或过大。
使用 @capgo/Tailwind-capacitor,您可以用单个外壳来表示相同的填充。 pt-safe pb-safe px-safe 设置__CAPGO_KEEP_0__ iOS
设置CapacitoriOS contentInset 首先 never 在
In capacitor.config.ts) 来拥有安全区域: contentInsetMode: 'css'混合__CAPGO_KEEP_0__的自动内容内边距与 CSS
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'dist',
ios: {
contentInset: 'never',
},
};
混合 Capacitor 自动内容内边距与 CSS env(safe-area-inset-*) 填充是双倍间距的常见原因。
找到真正溢出的元素
通常的凶手是使用 100vw,Tailwind w-screen,一个固定的像素宽度,或者一个很大的 min-width.
在Safari Web Inspector中,运行:
[...document.querySelectorAll('*')]
.filter(el => el.scrollWidth > document.documentElement.clientWidth)
.map(el => ({
el,
tag: el.tagName,
class: el.className,
scrollWidth: el.scrollWidth,
clientWidth: document.documentElement.clientWidth,
}));
当可能时,使用 w-screen 代替 w-full ,当可能时。许多水平溢出问题来自 100vw / w-screen,重复的安全区域填充,或者一个固定的宽度容器——而不是来自视口元标签本身。
结论
Capacitor是基于现有Web项目构建原生应用的优秀选择,提供了一个简单的方式来共享code并保持一致的UI。
并且随着__CAPGO_KEEP_0__的加入 Capgo这使得您可以轻松地将实时更新添加到您的应用中,确保您的用户始终可以访问最新的功能和修复
如果您想学习如何将Capgo添加到您的React应用中,请查看下一篇文章
继续阅读《使用React和Capacitor构建移动应用》
如果您正在使用 《使用React和Capacitor构建移动应用》 来规划CI/CD自动化,连接它到 Capgo CI/CD 在Capgo CI/CD中 Capgo 原生构建 在Capgo Native Builds中 Capgo 集成 为产品工作流程在 Capgo 集成中 CI/CD 集成 为 CI/CD 集成的实现细节 GitHub 动作集成 为 GitHub 动作集成的实现细节