跳过主要内容
教程

使用纯 React.js 和 Capacitor 构建移动应用

关于如何将 React.js 网站应用转换为原生移动应用,利用 Capacitor,并添加 Capgo Native Navigation、过渡和 iOS 布局最佳实践的指南。

文章来源

马丁·多纳迪厄

作者

瓦莱里亚

审阅者

乔丹

编辑

Building Mobile Apps with Pure React.js and Capacitor

This tutorial will walk you through crafting a mobile application using React and Capacitor. By the end, you’ll know how to morph a React.js web app into a native mobile application with Capacitor, and add a native feel with Capgo Native Navigation and Transitions.

Capacitor enables the easy transformation of your React.js web app into a native mobile application, requiring no substantial alterations or learning of new strategies such as 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 。我们稍后会回到这个问题。首先,让我们了解如何将 __CAPGO_KEEP_0__ 集成到我们的 React 应用程序中。

将 Capacitor 集成到您的 React.js 应用程序中

Integrating Capacitor into Your React.js App

命令 sync command.

First, we’ll install the Capacitor CLI as a development dependency and set it up within our project. During the setup, accept the default values for name and bundle ID by pressing “enter.”

我们将在此处继续...

最后,我们将添加平台,并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

The ios 和 android android

为了以后访问 Android 项目,安装 目录现在出现在您的React.js项目中。要访问Android项目,请安装 Xcode.

。对于iOS,您需要Mac,并应安装 Xcode 在您的 capacitor.config.json 文件中,如下所示:

{
  "appId": "com.example.app",
  "appName": "my-app",
  "webDir": "build",
  "bundledWebRuntime": false
}

运行构建命令并同步您的项目与Capacitor:

npm run build
npx cap sync

该 npm run build 命令将构建您的React.js项目,而 npx cap sync 将使Webcode准确地放置在本机平台的正确位置,以便在应用程序中执行。

现在,运气好,没有错误,您的React.js应用程序应该已经准备好在设备上发布!

构建和部署您的本机应用

开发iOS应用需要 Xcode,而Android应用则需要 安卓 studio如果您打算在应用商店上发布应用,必须在苹果开发者计划(Apple Developer Program)中注册iOS,和谷歌Play控制台(Google Play Console)中注册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 实时重载

Modern development frameworks usually come with hot reload, and luckily, you can have the same with Capacitor but 在移动设备上!

You can make your locally hosted application accessible with live reload on your network by having the Capacitor app load the content from a specific 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 插件。让我们安装一个简单的插件,分享插件 ,它会提示本机分享对话框:Share

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.

下一步,您可以通过 Capgo 导航和过渡来使应用程序在 iOS 和 Android 上更具本地感,并解决常见的 iOS 布局问题,例如水平溢出或裁剪安全区域。

原生感知的UI与Capgo原生导航和过渡

我已经多年来与 Ionic 为了构建跨平台应用,但将其与 React 集成起来是很hack的,而且当你已经有了它时,很少值得。 Tailwind CSS.

为了在 React + Capacitor 应用中实现原生移动体验,使用 Capgo 插件而不是仅限于 web 的 UI 套件,如 Konsta UI。

  • @capgo/capacitor-原生导航 ——原生导航栏、Liquid Glass iOS标签栏和Android模糊标签栏样式。您的React路由器保留路由状态;插件拥有原生浏览器。
  • @capgo/capacitor-过渡 ——在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标签栏(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>;
}

在 React 应用中使用 Capacitor cap-router-outlet, cap-page,和 cap-content,并调用 setDirection('forward') 或 setDirection('back') context

查看完整指南: 使用@capgo/capacitor原生导航 和 使用@capgo/capacitor过渡.

安全区域

在Tailwind CSS中,使用 @capgo/tailwind-capacitor (发布于 tailwind-capacitor npm safe-areas utilities 和其他 Capacitor 兼容的 Tailwind 插件

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-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);
}

将所有页面内容包装在 .app-shell中。 复制安全区域内边距到头部、模态对话框和布局包装器中,通常会使 UI 看起来被裁剪或过大。

使用 @capgo/Tailwind-capacitor,您可以用类似于 pt-safe pb-safe px-safe 的工具来表达相同的内边距。

将Capacitor iOS contentInset 设置为 never 首先

在 capacitor.config.ts中,优先使用原生内边距禁用,并让 CSS (或 Native Navigation 的) contentInsetMode: 'css') 来拥有安全区域:

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

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

找到真正溢出的元素

通常的原因是使用 100vw,Tailwind w-screen,一个固定的像素宽度,或者一个很大的 min-width.

In 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,重复的安全区域内边距,或者一个固定宽度的容器——而不是来自视口元标签本身。

结论

Capacitor 提供了基于现有 web 项目构建原生应用的无缝方式,提供了简单的方式来共享 code 并保持一致的 UI。

感谢技术如 Capacitor,从 React.js web 应用中构建移动应用已经变得更加容易。将您的 web 开发技能提升到下一个水平,创造出令人印象深刻的原生移动应用。快乐编码!

了解更多关于如何快速推进您的应用开发过程 注册免费账户 今天

Keep going from Building Mobile Apps with Pure React.js and Capacitor

如果您正在使用 Building Mobile Apps with Pure React.js and Capacitor 与其连接 使用 @capgo/capacitor-live-activities 为在 Using @capgo/capacitor-live-activities 中的原生能力 使用 @capgo/capacitor-live-activities 使用@capgo/capacitor-live-activities进行实现细节 使用@capgo/capacitor-video-player 使用@capgo/capacitor-video-player进行原生能力 @capgo/capacitor-视频播放器 使用@capgo/capacitor-video-player进行实现细节,并 使用@capgo/capacitor-native-navigation 使用@capgo/capacitor-native-navigation进行原生能力

实时更新Capacitor应用

当web层bug实时更新时,通过Capgo将修复推送到应用,而不是等待几天的应用商店审批。用户在后台接收更新,而原生更改仍在正常审批路径中。

最新博客文章

Capgo 为您提供创建专业移动应用所需的最佳见解