跳过主要内容
教程

Building Mobile Apps with React and Capacitor

Learn how to build a mobile app using React, Capacitor, and add Capgo Native Navigation, Transitions, and iOS layout best practices.

文章来源

马丁·多纳迪尤

作者

瓦莱里亚

审阅者

乔丹

编辑

Building Mobile Apps with React and Capacitor

In本教程中,我们将从新建一个 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 allows you to easily convert your React web application into a native mobile app without significant modifications or learning a new skill like React Native.

Capacitor

This tutorial will guide you through the process, starting with a new React app and then incorporating Capacitor to move into the realm of native mobile apps. You can also use Capgo Native Navigation, Transitions, and tailwind-capacitor for safe areas.

About Capacitor

Capacitor

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!

Capacitor

虽然有多种方法来启动 React 应用,但本教程中我们将使用最简单的方法,提供一个空白的 React 应用:

npx create-react-app my-app

为了创建一个原生移动应用,我们需要一个 export 项目的 。因此,让我们在我们的 中添加一个简单的脚本,用于构建和导出 React 项目:

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}

您现在可以无忧无虑地 npm run build ,并应该能够在项目根目录看到一个新鲜的

This folder will be used by Capacitor later on, but for now, we must set it up correctly.

Adding Capacitor to Your React App

将 Capgo 添加到您的 React 应用中 sync 将任何 Web 应用打包到原生移动容器中,我们需要遵循几个初始步骤,但之后只需执行一个单独的

首先,我们可以安装 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

到目前为止,您应该能够观察到新的 ioscontext android

文件夹在您的React项目中。

这些是真正的本机项目! Android Studio. For iOS, you need a Mac and should install Xcode.

Additionally, you should find a capacitor.config.ts file in your project, which contains some fundamental Capacitor settings utilized during the sync. The only thing you need to pay attention to is the 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 到原生平台的正确位置,以便它们可以在应用中显示。

此外,同步命令可能会更新原生平台并安装插件,因此当您安装一个新的 Capacitor 插件 npx cap sync 时,需要重新运行

命令。

您可能已经不经意间完成了,

所以让我们在设备上看看应用吧! Xcode 已安装, 需要安装 Android Studio

If you’re new to native mobile development, you can use the Capacitor CLI to easily open both native projects:

npx cap open ios
npx cap open android

如果您是新手,

可以使用

轻松打开两个原生项目:

设置原生项目后,

将应用部署到连接设备上非常容易。在Android Studio中,只需等待所有内容就绪,然后您可以在不更改任何设置的情况下将应用部署到连接设备上。以下是示例:

android-studio-run

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

Capacitor 实时重载

到目前为止,你可能已经习惯了所有现代框架都具有热重载的功能,好消息是你可以在移动设备上实现相同的功能 而且只需花费很少的努力 在你的网络上通过实时重载访问你的本地托管应用

通过让__CAPGO_KEEP_0__ app从特定的URL加载内容 第一步是确定你的本地IP地址。如果你使用Mac,可以通过在终端中运行以下命令来找到它 by having the Capacitor app load the content from the specific URL.

然后查找IPv4地址

ipconfig getifaddr en0

我们可以通过在文件中添加另一个条目来指示__CAPGO_KEEP_0__从服务器直接加载应用

ipconfig

文件

Capacitor 实时重载 capacitor.config.ts 到目前为止,你可能已经习惯了所有现代框架都具有热重载的功能,好消息是你可以在移动设备上实现相同的功能而且只需花费很少的努力

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应用程序中更改了什么内容, 应用程序将自动重新加载

并显示更改! You can now deploy your app one more time through Android Studio or Xcode. After that, if you change something in your React app, the app will automatically reload

请注意 如果您安装了新插件,如摄像头插件,它仍然需要重新构建您的本机项目。这是因为本机文件已更改,而不能在飞行中完成。

请注意,您应该在配置中使用正确的IP和端口。上面的code块显示了用于演示目的的默认React端口。

使用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

点击按钮后,您可以看到美丽的原生分享对话框在行动!

react-capacitor-share

接下来,您可以使应用程序在iOS和Android上感觉更原生,使用Capgo导航和过渡,并修复常见的iOS布局问题,导致水平溢出或裁剪安全区域。

原生感知UI使用Capgo原生导航和过渡

我已经工作了几年 Ionic 来构建跨平台应用程序,但将其与React集成起来很hacky,并且很少值得在您已经有 Tailwind CSS.

在一个React + Capacitor应用程序中,使用Capgo插件而不是仅限Web的UI套件,如Konsta UI来实现原生移动感知:

  • @capgo/capacitor-native-navigation —原生导航栏,Liquid Glass iOS上的标签栏,Android上的模糊标签栏样式。您的React路由器保留路由状态;插件拥有原生浏览器。
  • @capgo/capacitor-transitions ——— Ionic 风格的页面过渡和 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') 在导航之前执行。请勿重复 Web 头部或底部,当本机导航拥有这些表面时。

查看完整指南: 使用 @capgo/capacitor-native-navigation@capgo/capacitor-transitions.

安全区域

在Tailwind CSS中,使用 @capgo/tailwind-capacitor (发布于 tailwind-capacitor @npm safe-areas utilities and other Capacitor-friendly Tailwind plugins:

bun add -D tailwind-capacitor

实用工具和其他 src/index.css:

@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";

@__CAPGO_KEEP_0__-友好的Tailwind插件: pt-safe, pb-safepx-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);
}

创建一个单独的应用程序壳并在其中应用安全区域填充 — 不要在多个嵌套组件中: .app-shell将所有页面内容包装在 中:

With @capgo/tailwind-capacitor,你可以使用类似于 pt-safe pb-safe px-safe on that single shell.

设置CapacitoriOS contentInsetnever 首先

In capacitor.config.ts,更倾向于使用原生边距禁用,并让CSS(或原生导航的) contentInsetMode: 'css')来控制安全区域:

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'dist',
  ios: {
    contentInset: 'never',
  },
};

混合Capacitor的自动内容边距与CSS env(safe-area-inset-*) padding是双倍间距的常见原因。

找到真正的溢出元素

通常的罪魁祸首是使用 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,
  }));

使用 Tailwind,替换 w-screen 当可能时。许多水平溢出问题来自 w-full , 重复的安全区域填充, 或一个固定宽度容器 —— 不是来自视口元标签本身。 100vw / w-screen结论

__CAPGO_KEEP_0__ 是一个基于现有 web 项目构建原生应用的优秀选择,提供了一个简单的方式来共享 __CAPGO_KEEP_1__ 并保持一致的 UI。

Capacitor is an excellent option for building native applications based on an existing web project, offering a simple way to share code and maintain a consistent UI.

__CAPGO_KEEP_2__ Capgo让您的应用程序拥有实时更新功能,使您的用户始终能够访问最新的功能和 bug 修复。

如果您想学习如何将 Capgo 添加到您的 React 应用程序中,请查看下一篇文章:

继续阅读《使用 React 和 Capacitor 构建移动应用》

如果您正在使用 《使用 React 和 Capacitor 构建移动应用》 来规划 CI/CD 自动化,连接它与 Capgo CI/CD 为 Capgo CI/CD 产品工作流程 Capgo 原生构建 为 Capgo 原生构建 产品工作流程 Capgo 集成 为Capgo产品工作流程中的集成 CI/CD集成 为CI/CD集成中的实现细节 GitHub动作集成 为GitHub动作集成中的实现细节

实时更新 Capacitor 应用

当 web-layer 错误活跃时,通过 Capgo 将修复推送到应用,而不是等待几天的应用商店审批。用户在后台接收更新,而原生更改保持在正常审批路径中。

来自 Martin 的人性化支持

立即开始

最新博客文章

Capgo 给您需要创建真正专业移动应用所需的最佳见解。