本教程将指导您使用 React 和 Capacitor 创建一个移动应用。通过此过程,您将了解如何将 React.js 网页应用转换为具有 Capacitor 和 Capgo Native Navigation 和 Transitions 的原生移动应用。
Capacitor 可以轻松将您的 React.js 网页应用转换为原生移动应用,无需进行重大更改或学习新的策略,如 React Native。
该过程涉及几个简单的步骤,很快您的 React.js 应用就会成为一个功能齐全的移动应用。因此,请继续阅读,我们将指导您完成此旅程。
Capacitor 概述
CapacitorJS 是一个革命性的工具。它可以与任何 web 项目无缝集成,并将您的应用包装在一个原生 webview 中,同时生成 Xcode 和 Android Studio 项目。通过其插件,您还可以访问像摄像头这样的原生设备功能,通过 JS 桥进行访问。
Capacitor 提供了一种简单的方式来创建原生移动应用,无需任何麻烦或陡峭的学习曲线。其简单的 API 和流线化的功能使其易于在您的项目中集成。
设置您的 React.js 应用
让我们使用最简单的方法来启动一个 React 应用。我们将使用 npm 包管理器创建一个新 React 应用:
npx create-react-app my-app
将我们的项目转换为原生移动应用所需的 export 。
我们将在稍后返回这个问题。首先,让我们了解如何将 Capacitor 集成到我们的 React 应用中。
在 React.js 应用中集成 Capacitor
可能需要一些详细的初始设置步骤,但之后更新本地应用包装器只需运行一个 sync 命令即可。
首先,我们将安装 Capacitor CLI 作为开发依赖项,并在项目中设置它。在设置过程中,按“回车”键接受默认值即可。
接下来,我们将安装核心包和 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 和 android 目录已在 React.js 项目中出现。
为了以后访问 Android 项目,请安装 Android Studio为了在 iOS 上使用 Capgo,您需要一台 Mac,并且应该安装 Xcode.
接下来,更新 webDir 在您的 capacitor.config.json 文件中如图所示:
{
"appId": "com.example.app",
"appName": "my-app",
"webDir": "build",
"bundledWebRuntime": false
}
运行构建命令并同步您的项目与 Capacitor:
npm run build
npx cap sync
命令将构建您的 React.js 项目,而 npm run build 将使 web __CAPGO_KEEP_0__ 在各个原生平台的准确位置执行,以便在应用中执行。 npx cap sync 将 web code 整合到原生应用中
现在,带着一点运气和没有错误,你的React.js应用应该已经准备好在设备上发布了!
构建和部署您的原生应用
开发iOS应用需要 Xcode, Android Studio。如果您打算在应用商店上发布您的应用,则必须加入Apple Developer Program(苹果开发者计划)来开发iOS应用和Google Play Console(谷歌Play控制台)来开发Android应用。
The Capacitor CLI simplifies the process of opening both native projects:
npx cap open ios
npx cap open android
一旦您的原生项目设置完成,部署您的应用到连接的设备就是一个简单的过程。
对于Android Studio,等待所有内容加载完毕,然后将您的应用部署到连接的设备上。
对于Xcode,建立您的签名账户以将您的应用部署到真实设备而不是仅仅是模拟器。完成后,只需点击播放即可在您的连接设备上运行应用,您可以在顶部选择。
如果一切顺利,您将会将您的React.js Web应用转换为原生移动应用!
Capacitor Live Reload
现代开发框架通常都有热重载功能,幸运的是,你也可以在Capacitor中实现这一点,但 在你的移动设备上!
你可以让你的本地托管应用在你的网络上通过live reload来访问,通过让Capacitor app从一个特定的URL加载内容
首先,确定你的本地IP地址。在Mac上,你可以通过在终端中运行 ipconfig getifaddr en0 来实现。在Windows上,执行 ipconfig 并查找IPv4地址
之后,指示Capacitor从服务器直接加载应用程序,通过在你的 capacitor.config.ts 文件中添加另一个参数:
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'build',
bundledWebRuntime: false,
server: {
url: 'http://192.168.x.xx:3000',
cleartext: true
}
};
export default config;
确保使用准确的IP和端口。运行 npx cap copy 来应用这些更改到我们的本地项目中
在通过Android Studio或Xcode重新部署你的应用程序后,任何React应用程序的更改都会自动重载并在你的应用程序中显示!
请注意,如果安装了新插件,如摄像头,它需要重新构建您的原生项目。这是因为原生文件已经改变,并且无法在实时更新。
使用Capacitor插件
让我们快速了解如何使用Capacitor插件。让我们安装一个简单的插件, 分享插件,它会弹出原生的分享对话框:
npm i @capacitor/share
要使用它,需要导入包并从我们的应用中调用相应的 share() 函数。考虑到 App.js:
import { Share } from '@capacitor/share';
function ShareButton() {
const share = async () => {
await Share.share({
title: 'React App',
text: 'Visit this React App',
url: 'http://localhost:3000',
dialogTitle: 'Share with...'
});
};
return (
<button onClick={share}>
Share
</button>
);
}
export default ShareButton;
安装新插件后,请记住再次同步您的React项目使用 npx cap sync.
接下来,您可以使应用在iOS和Android上感觉更原生,使用Capgo导航和过渡,修复常见的iOS布局问题,导致水平溢出或裁剪安全区域。
原生感知UI与Capgo原生导航和过渡
我已经工作了多年 ionic 为了构建跨平台应用,但将其与 React 集成起来是hacky且不值得的,尤其是当你已经有了 Tailwind CSS.
在一个 React + Capacitor 应用中,为了获得原生移动的感觉,使用 Capgo 插件而不是像 Konsta UI 这样的仅限 web UI 套件:
- @capgo/capacitor-native-navigation — 原生导航栏,iOS 上的 Liquid Glass tab bar,Android 上的模糊 tab bar 风格。你的 React 路由器保留了路由状态;插件拥有原生浏览器。
- @capgo/capacitor-transitions — 在 WebView层中实现Ionic风格的页面过渡和iOS的边缘滑动返回,避免采用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',
},
});
渲染一个Liquid Glass tab bar(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>;
}
Wrap routed pages in cap-router-outlet, cap-page,和 cap-content,并调用 setDirection('forward') 或 setDirection('back') 在导航之前。不要在原生导航拥有这些表面的情况下重复web头部或底部。
查看完整指南: 使用@capgo/capacitor-原生导航 和 使用@capgo/capacitor-过渡.
安全区域与Tailwind
在Tailwind CSS中使用设备安全区域,请使用 @capgo/tailwind-capacitor (发布于 tailwind-capacitor 在 npm 中发布。它提供 safe-areas 工具和其他 Capacitor 友好的 Tailwind 插件:
bun add -D tailwind-capacitor
在 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 __CAPGO_KEEP_0__
确保视口元标签正确应用
在 index.html 内部 <head>:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
仅从一个根包装器中处理 iOS 安全区域
创建一个单独的应用 shell,并在其中应用安全区域填充,而不是在多个嵌套组件中:
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);
}
将所有页面内容包装在 .app-shell在头部、模态对话框和布局包装器中重复应用安全区域填充,通常会使 UI 看起来被裁剪或过大。
使用 @capgo/tailwind-capacitor,您可以使用类似 pt-safe pb-safe px-safe 的工具表达相同的填充。
在单个 shell 上设置 Capacitor iOS contentInset 首先 never In
, 优先使用原生 inset 并让 CSS (或 Native Navigation 的) capacitor.config.ts混合 __CAPGO_KEEP_0__ 自动内容 inset 与 CSS contentInsetMode: 'css'padding 是双倍间距的常见原因。
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'build',
ios: {
contentInset: 'never',
},
};
Mixing Capacitor’s automatic content inset with CSS env(safe-area-inset-*) 通常的凶手是使用
, Tailwind
, 固定像素宽度或较大的 100vw在 Safari Web Inspector 中运行: w-screen在 Safari Web Inspector 中运行: 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,
}));
使用Tailwind,尽可能地替换 w-screen with w-full 当出现水平溢出问题时,通常是因为 100vw / w-screen、重复的安全区域填充或固定宽度容器 — 而不是viewport meta标签本身的问题。
结论
Capacitor提供了一个无缝的方式来基于现有的web项目构建原生应用,提供了一个简单的方式来共享code并保持一致的UI。
感谢技术如Capacitor,从React.js web应用中构建移动应用已经变得更加容易。将您的web开发技能提升到下一个水平,通过打造出色的原生移动应用。Happy coding!
要了解如何如何快速推进您的应用开发过程,请 注册免费账户 今天。
继续从Building Mobile Apps with Pure React.js和Capacitor
如果您正在使用 使用纯React.js构建移动应用和Capacitor 为native媒体和界面行为制定计划,连接它 使用@capgo/capacitor-live-activities 为使用@capgo/capacitor-live-activities的native能力 @capgo/capacitor-live-activities 为@capgo/capacitor-live-activities的实现细节 使用@capgo/capacitor-video-player 为使用@capgo/capacitor-video-player的native能力 @capgo/capacitor-video-player 为@capgo/capacitor-video-player的实现细节, 使用@capgo/capacitor-native-navigation 为使用@capgo/capacitor-native-navigation的native能力