跨端开发
"一套代码,多处运行"是前端开发的长期追求。从 Web 到移动端、桌面端、小程序,跨端方案层出不穷。理解每种方案的渲染原理,才能做出正确的选型。
一、跨端方案全景
| 方案 | 目标平台 | 渲染原理 | 代表 |
|---|---|---|---|
| Web(响应式) | 浏览器 | 浏览器渲染 | PWA、移动端适配 |
| React Native | iOS / Android | 原生组件桥接 | RN、Expo |
| Flutter | iOS / Android / Web / 桌面 | 自绘引擎(Skia) | Flutter |
| Taro | 小程序 / H5 / RN | 编译成多端代码 | Taro 3 |
| 小程序原生 | 微信 / 支付宝等 | 小程序运行时 | 原生小程序 |
| Electron | Windows / macOS / Linux | Chromium + Node | VS Code |
| Tauri | 桌面 | 系统 WebView + Rust | Tauri 2 |
| Capacitor | 移动端打包 | 壳 + WebView | Ionic |
text
按"渲染方式"分三类:
1. Web 技术渲染:H5、Taro H5、Capacitor(WebView)
2. 原生组件渲染:React Native、Taro RN
3. 自绘引擎渲染:Flutter(不依赖系统控件)二、React Native
React 语法编写,但渲染的不是 DOM,而是原生组件。
jsx
import { View, Text, Button } from "react-native";
function Home() {
return (
<View style={{ padding: 16 }}>
<Text style={{ fontSize: 18 }}>你好,RN</Text>
<Button title="点击" onPress={() => console.log("tapped")} />
</View>
);
}2.1 桥接原理
text
JS 线程(业务逻辑、React 组件)
→ 通过 Bridge(JSON 消息)异步通信
→ 原生线程(iOS/Android 渲染真实原生控件)| 概念 | 说明 |
|---|---|
| JS 线程 | 运行 JS 逻辑,不与 UI 同线程 |
| 原生线程 | 渲染 UINavigationView / ViewGroup |
| Bridge | 序列化消息桥,跨线程调用原生能力 |
| 原生模块 | 用 Objective-C / Kotlin 写,JS 调用 |
2.2 架构演进
| 版本 | 架构 | 变化 |
|---|---|---|
| RN 老架构 | Bridge 异步消息 | 消息序列化开销大,性能受限 |
| New Architecture | JSI(接口)+ Fabric + TurboModule | JS 直接调用原生,无桥接序列化 |
新架构(Fabric + TurboModules + JSI)的目标:同步调用、更快的启动与渲染,以及 Folly(共享内存)层面的优化。
三、Taro 小程序框架
Taro 让开发者用 React/Vue 语法编写,一次开发,编译到微信小程序、H5、React Native 等多端。
3.1 基本用法
jsx
// Taro 3(React 写法)
import Taro from "@tarojs/taro";
import { View, Text, Button } from "@tarojs/components";
export default function Index() {
const handleClick = () => {
Taro.showToast({ title: "你好,Taro", icon: "success" });
};
return (
<View className="page">
<Text>跨端小程序</Text>
<Button onClick={handleClick}>点我</Button>
</View>
);
}bash
npm install -g @tarojs/cli
taro init my-app # 可选 React / Vue / 框架版本
npm run dev:weapp # 编译到微信小程序
npm run dev:h5 # 编译到 H5
npm run dev:rn # 编译到 React Native3.2 编译原理
text
一套源码(React/Vue)
→ Babel + Webpack 按目标平台编译
→ 微信端:生成 wxml/wxss/js 小程序包
→ H5 端:生成标准 Web 应用
→ RN 端:生成 RN 工程| 对比 | Taro | uni-app |
|---|---|---|
| 语法 | React / Vue(可选) | Vue 为主 |
| 生态 | React 生态友好 | Vue 生态友好,插件市场丰富 |
| 平台支持 | 微信/支付宝/百度/字节/H5/RN | 微信/支付宝/H5/App(plus)/快应用 |
| 运行时 | Taro 3 无重编译运行时 | 编译期转换 |
Taro 3 的核心理念:"用小程序原生框架,组件与 API 由 Taro 提供"——编译后的代码贴近小程序原生,减小体积与运行时成本。
四、Electron 桌面
用 Web 技术构建桌面应用:Chromium 负责界面,Node.js 提供系统能力。
4.1 进程模型
text
主进程(Main Process)
├─ 创建窗口、管理生命周期
├─ 访问 Node API(文件、系统)
└─ 通过 IPC 与渲染进程通信
渲染进程(Renderer Process)
├─ 每个窗口一个,跑网页(Chromium)
├─ 默认无 Node 权限(安全隔离)
└─ 通过 IPC 向主进程请求能力javascript
// 主进程 main.js
const { app, BrowserWindow, ipcMain } = require("electron");
app.whenReady().then(() => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: { contextIsolation: true, nodeIntegration: false },
});
win.loadFile("index.html");
});
// 监听渲染进程请求,读取本地文件
ipcMain.handle("read-file", async (event, path) => {
return require("fs").readFileSync(path, "utf-8");
});javascript
// 渲染进程 renderer.js(通过 preload 暴露的安全 API)
const { readFile } = window.electronAPI;
const content = await readFile("C:/data.txt");| 概念 | 说明 |
|---|---|
| 主进程 | Node 环境,管窗口与系统能力 |
| 渲染进程 | 每个窗口一个,Chromium 渲染网页 |
| IPC | ipcMain / ipcRenderer 双向消息 |
| preload | 中间层,安全地暴露能力给渲染进程 |
| contextIsolation | 隔离渲染进程与 Node,安全关键开关 |
4.2 打包
bash
npm install -D electron-builder
npx electron-builder --win # 打包 Windows 安装包
npx electron-builder --mac # 打包 macOS 安装包五、Capacitor 与 Tauri
| 方案 | 定位 | 原理 | 特点 |
|---|---|---|---|
| Capacitor | 把 Web 应用打包成移动 App | 原生壳 + 系统 WebView | 改动最小,Ionic 配套 |
| Tauri | 轻量桌面应用 | 系统 WebView + Rust 后端 | 体积小(几 MB)、内存低、Rust 性能强 |
javascript
// Capacitor:在已有 Web 工程中接入
import { Capacitor } from "@capacitor/core";
document.addEventListener("deviceready", () => {
console.log("原生能力可用");
});text
Tauri 与传统 Electron 对比:
Electron:自带 Chromium(约 200MB 安装包)
Tauri:用系统 WebView + Rust(安装包几 MB,内存占用低)
代价:Tauri 需要 Rust 生态,跨平台一致性依赖系统 WebView六、方案选型对比
| 维度 | Web/H5 | React Native | Taro(小程序) | Electron | Tauri | Capacitor |
|---|---|---|---|---|---|---|
| 性能 | 中 | 接近原生 | 中 | 高(桌面) | 高 | 中 |
| 生态 | 最丰富 | 丰富 | 小程序生态强 | 桌面生态 | 较新 | Web 生态 |
| 学习成本 | 低 | 中(RN 概念) | 中 | 低(Web 即会) | 需 Rust | 低 |
| 安装体积 | 无 | 中等 | 小程序内 | 大 | 极小 | 中等 |
| 适用场景 | 内容型、工具型 | 重交互移动 App | 微信/支付宝生态 | 桌面工具 | 轻量桌面 | 已有 Web 做 App |
选型建议:目标平台是"微信生态"选 Taro/uni-app;重原生体验的移动 App 选 RN/Flutter;桌面工具 Electron 最快,追求轻量用 Tauri;已有网站要 App 壳用 Capacitor。
七、跨端代码组织与条件编译
跨端项目常见的做法:核心逻辑共享,端差异用条件编译隔离。
javascript
// 条件编译(Taro / uni-app 注释语法)
// #ifdef H5
console.log("只在 H5 生效");
// #endif
// #ifndef H5
console.log("小程序/RN 生效");
// #endifjavascript
// 运行时环境判断
import Taro from "@tarojs/taro";
const env = Taro.getEnv(); // 'WEAPP' | 'H5' | 'RN'text
跨端代码组织建议:
src/
common/ # 纯逻辑(与端无关,占比尽量大)
h5/ # 端差异实现(可选目录)
weapp/
rn/
原则:业务逻辑抽成纯函数/API 层,UI 与平台 API 尽量薄javascript
// API 层抽象:各端自行实现,业务只依赖抽象
// src/common/api.js
export function uploadFile(file) {
// 按环境分发到不同实现
if (env === "WEAPP") return Taro.uploadFile({ url: "/upload", filePath: file });
return fetch("/upload", { method: "POST", body: file });
}八、本地存储与登录态跨端方案
各端存储能力不同,需要做统一封装:
| 能力 | Web | RN | 小程序 | Electron |
|---|---|---|---|---|
| 键值存储 | localStorage | AsyncStorage | Taro.setStorageSync | localStorage / 文件 |
| 会话 | cookie / token | 内存 + 存储 | 无 cookie | cookie / 文件 |
| 安全存储 | 无(XSS 风险) | Keychain/Keystore | 小程序存储 | 系统钥匙串 |
javascript
// 统一存储封装
import Taro from "@tarojs/taro";
export const storage = {
get(key) {
if (env === "WEAPP") return Taro.getStorageSync(key);
return localStorage.getItem(key);
},
set(key, value) {
if (env === "WEAPP") return Taro.setStorageSync(key, value);
return localStorage.setItem(key, JSON.stringify(value));
},
};text
登录态流程(跨端通用):
登录接口换取 token
→ 写入统一存储层
→ 请求拦截器自动附加 token
→ token 过期 → 刷新 token / 跳登录页javascript
// 请求层自动带 token
async function request(url, options = {}) {
const token = storage.get("token");
const res = await fetch(url, {
...options,
headers: { Authorization: `Bearer ${token}`, ...options.headers },
});
if (res.status === 401) { // 未授权:清除登录态,跳登录
storage.remove("token");
redirectTo("/login");
}
return res;
}九、要点速查
| 概念 | 一句话记忆 |
|---|---|
| RN | JS 逻辑 + 原生组件渲染,Bridge 通信 |
| Taro | 一套代码编译到小程序 / H5 / RN |
| Electron | Chromium 界面 + Node 能力,主/渲染进程 |
| Tauri | 系统 WebView + Rust,极致轻量 |
| Capacitor | 原生壳套 Web 应用 |
| 条件编译 | 注释标记按端裁剪代码 |
| 登录态 | 统一存储层 + 请求拦截器 + 401 处理 |