Expo React Native 无原生开发

FreeGuideOnline 13阅读 2026-07-13

引言:用Expo开启React Native,告别原生配置的烦恼

React Native 让你用 JavaScript 构建真正的移动应用,但传统开发往往需要同时处理 Android、iOS 的原生代码、证书、依赖和编译问题。Expo 的出现彻底改变了这一点。Expo 是一个围绕 React Native 的免费、开源工具链和服务平台,让你可以在不接触任何原生代码、无需安装 Android Studio 或 Xcode 的情况下,完成从开发、测试到构建的全流程。本教程将带你从零开始,用 Expo 搭建一个完整的移动应用,全程无需原生开发经验。

什么是 Expo?为什么说它「无原生开发」?

Expo 由两个主要部分组成:Expo SDKExpo Application Services (EAS)。SDK 提供了大量跨平台的 Native API(如相机、地理位置、通知等),这些 API 已经为你封装好,只需通过 JavaScript 调用。EAS 则提供云构建、提交和更新服务,让你直接在云端生成应用安装包,无需在本地配置复杂的原生构建环境。

所谓「无原生开发」,是指你始终工作在 Managed Workflow(托管工作流)下。你永远不需要直接编辑 Android 的 AndroidManifest.xml、iOS 的 Info.plist,也不需要维护 android/ios/ 目录。所有原生模块的管理、版本兼容、权限配置都由 Expo 工具代劳。当你需要更多控制权时,也可以选择 Eject 到 Bare Workflow,但那已经超出了本教程的范围——我们只专注于纯 Expo 的无原生体验。

准备工作:安装 Expo CLI 并创建项目

开始之前,确保你的电脑上安装了 Node.js(建议 18.x 或以上版本)和 npmyarn

安装 Expo CLI

Expo 官方推荐使用本地开发服务器(npx expo),无需全局安装。但为了更流畅地创建项目,你可以使用 create-expo-app 工具:

npx create-expo-app@latest MyFirstApp

执行后会在当前目录下生成 MyFirstApp 文件夹,并自动安装基本依赖。之后进入项目:

cd MyFirstApp

在真机或模拟器上预览

无需任何原生开发环境,你就能立即看到应用效果。有三种方式:

  1. Expo Go 客户端(手机):在 iPhone 的 App Store 或 Android 的应用商店下载 “Expo Go”。确保手机和电脑在同一 Wi-Fi 下。然后在项目根目录运行:

    npx expo start
    

    终端会显示一个二维码,用 Expo Go 扫描即可打开应用。

  2. Android 模拟器:如果你本地安装了 Android Studio 并创建了模拟器(仅需安装,不是开发必须),Expo 会自动检测并启动应用。

  3. iOS 模拟器:仅限 macOS,且需要安装 Xcode。同样,Expo 会自动启动。

对纯粹的「无原生开发」追求者,直接使用 Expo Go 是首选。你甚至不需要安装任何 Android 或 iOS 工具,只需一个手机和 Wi-Fi。

Hello World:修改你的第一个界面

打开项目根目录下的 App.js(或 App.tsx)。替换其内容为以下简单示例:

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>欢迎来到 Expo</Text>
      <Text style={styles.subtitle}>无需原生开发的移动应用</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 8,
  },
  subtitle: {
    fontSize: 16,
    color: '#555',
  },
});

保存文件,Expo Go 中的界面会立即刷新(Fast Refresh)。这便是 Expo 无原生开发的核心体验:改代码,即时看效果,无需等待漫长的原生编译。

Expo SDK:无需原生模块即可访问设备功能

Expo 最大的优势在于内置了丰富的 API 库,这些库完全不需要你手动链接原生模块。举例几个常用模块:

1. 使用相机

安装相机库:

npx expo install expo-camera

在代码中请求权限并打开相机:

import { Camera, CameraType } from 'expo-camera';
import { useState, useEffect } from 'react';
import { Button, View, Text } from 'react-native';

export default function CameraScreen() {
  const [hasPermission, setHasPermission] = useState(null);
  const [type, setType] = useState(CameraType.back);

  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestCameraPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);

  if (hasPermission === null) return <View />;
  if (hasPermission === false) return <Text>没有相机权限</Text>;

  return (
    <View style={{ flex: 1 }}>
      <Camera style={{ flex: 1 }} type={type}>
        <Button
          title="翻转摄像头"
          onPress={() => setType(type === CameraType.back ? CameraType.front : CameraType.back)}
        />
      </Camera>
    </View>
  );
}

你无需触碰一句原生代码,权限请求和相机界面全部由 Expo 库管理。

2. 地理位置

安装:

npx expo install expo-location

获取当前位置:

import * as Location from 'expo-location';
import { useState, useEffect } from 'react';
import { Text, View } from 'react-native';

export default function LocationScreen() {
  const [location, setLocation] = useState(null);

  useEffect(() => {
    (async () => {
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') return;
      let loc = await Location.getCurrentPositionAsync({});
      setLocation(loc);
    })();
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      {location ? (
        <Text>纬度: {location.coords.latitude}, 经度: {location.coords.longitude}</Text>
      ) : (
        <Text>正在获取位置...</Text>
      )}
    </View>
  );
}

3. 本地通知

安装:

npx expo install expo-notifications

发送一个即时通知:

import * as Notifications from 'expo-notifications';
import { Button, View } from 'react-native';

export default function NotificationScreen() {
  const scheduleNotification = async () => {
    await Notifications.scheduleNotificationAsync({
      content: {
        title: "提醒 ⏰",
        body: '这是一条来自 Expo 的无原生通知!',
      },
      trigger: null, // 立即触发
    });
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="发送通知" onPress={scheduleNotification} />
    </View>
  );
}

所有这些功能都运行在 Managed Workflow 中,你编写的代码纯粹是 JavaScript/TypeScript,零原生文件操作。

构建独立应用(APK / IPA)—— 仍然无需原生开发

开发完成后,你需要生成可以上传到应用商店的安装包。传统方式需要你打开 Xcode 或 Android Studio 进行复杂配置。Expo 的 EAS Build 服务可以直接在云端打包。

配置 EAS Build

首先安装 EAS CLI:

npm install -g eas-cli

然后在项目根目录执行:

eas build:configure

这会生成一个 eas.json 配置文件,你可以看到默认的 production 配置。最简单的构建命令:

  • Android 构建:

    eas build --platform android
    
  • iOS 构建:

    eas build --platform ios
    

执行后,EAS 会要求你登录 Expo 账号(免费注册),随后代码会被上传到云端,在 Expo 的服务器上完成原生打包。几分钟后你会收到一个下载链接,直接获得 .apk(Android)或 .ipa(iOS)文件。

整个过程你不需要安装 Android Studio 或 Xcode(除非需要在模拟器测试),也不需要管理签名证书(EAS 可以自动生成和管理)。对于 iOS,你仍然需要 Apple 开发者账号,但无需手动操作 Xcode。

路由与导航:使用 Expo Router(基于文件的路由系统)

Expo 官方推出了 Expo Router,它参考了 Next.js 的文件约定,让你通过目录结构自动生成导航。它基于 React Navigation,但更为简洁。

在项目中使用 Expo Router,需要在创建项目时选择模板,或者通过以下步骤添加:

  1. 安装依赖:

    npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
    
  2. 修改 package.json 中的入口文件为 expo-router/entry

  3. 在项目根目录创建 app 文件夹。

现在,app/index.js 将成为首页,app/about.js 自动成为 /about 路由。你可以在文件中导出 React 组件。

示例 app/index.js

import { Link } from 'expo-router';
import { View, Text } from 'react-native';

export default function Home() {
  return (
    <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
      <Text>首页</Text>
      <Link href="/about">前往关于页面</Link>
    </View>
  );
}

示例 app/about.js

import { View, Text } from 'react-native';

export default function About() {
  return (
    <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
      <Text>关于我们</Text>
    </View>
  );
}

Expo Router 还支持深层链接和 Web 适配,你甚至可以用同一套代码生成 Web 应用,完全无原生负担。

常见问题与注意事项

  • 某些原生模块不兼容:如果你必须使用 Expo SDK 不包含的原生模块,才需要考虑 Eject。大多数常见功能已被 Expo SDK 覆盖(详见 https://docs.expo.dev/versions/latest/ )。
  • 本地开发时的网络问题:确保手机和电脑在同一网络,或者使用 USB 连接进行隧道模式(npx expo start --tunnel)。
  • 使用自定义原生代码:如果在 Managed Workflow 下无法满足需求,可以迁移到 Bare Workflow(此时仍可使用 Expo 工具,但需要原生开发知识)。本教程只探讨「无原生开发」的场景,所以不深入。

总结:你已经可以构建完整的移动应用

通过本教程,你学会了:

  • 使用 create-expo-app 创建项目
  • 借助 Expo Go 在真机上实时预览,无需原生环境
  • 调用 Expo SDK 中的相机、定位、通知等设备功能,代码纯 JavaScript
  • 使用 EAS Build 在云端打包发布版本
  • 利用 Expo Router 实现页面导航

最重要的是,以上所有步骤都没有要求你打开 Android Studio、Xcode,或者编辑任何原生文件。 这正是 Expo 「无原生开发」理念的体现。对于个人开发者、初创团队或快速原型设计来说,Expo 是最高效的 React Native 开发方式。

想要继续深入?可以访问 Expo 官方文档(https://docs.expo.dev)查看 SDK 的完整 API 参考和更多实用指南。现在就动手创建你的第一个 Expo 应用吧!