vite-plugin-react-native
v1.0.1
Published
Vite plugin for React Native web compatibility
Downloads
241
Maintainers
Readme
vite-plugin-react-native
让 React Native 在 Vite 上完美跑 Web —— 一套插件搞定 RN 到 Web 的别名、虚拟模块、构建与依赖优化,无需 Rolldown,兼容 Vite 4~7。
定位
- 同一套 RN 代码,用 Vite 构建 Web 端,开发体验与构建速度兼顾。
- 自动处理
react-native→react-native-web、常用 RN 库的 Web 占位实现、以及 Reanimated / Expo / CSS Interop 等兼容。 - 可选集成 react-native-router-dom,未安装时不影响使用。
功能概览
| 能力 | 说明 |
|------|------|
| react-native → react-native-web | 别名 + 扩展名 .web.* 优先解析 |
| react-native-safe-area-context | 虚拟模块,Web 下 SafeAreaProvider / useSafeAreaInsets 等 |
| react-native-screens | 虚拟模块,Screen / ScreenContainer / enableScreens 等 |
| react-native-gesture-handler | 虚拟模块,GestureHandlerRootView / GestureDetector 等占位,避免 Web 报错 |
| react-native-router-dom | 可选:安装则自动解析并参与预构建 |
| react-native-css-interop | 自动修补 doctor 检查,保证 Vite 下可构建 |
| define | __DEV__、process.env.NODE_ENV、EXPO_OS、_WORKLET 等 |
| optimizeDeps | 预置 RN 生态常用包,并与用户配置合并 |
安装
npm install vite-plugin-react-native react-native-web react react-dom
# 或
pnpm add vite-plugin-react-native react-native-web react react-dom可选(按需):
- 路由:
react-native-router-dom - 动画:
react-native-reanimated - 样式:
react-native-css-interop、NativeWind 等
使用
最简配置
// vite.config.ts
import { defineConfig } from 'vite';
import { reactNative } from 'vite-plugin-react-native';
export default defineConfig({
plugins: [reactNative()],
});推荐:配合 React 插件(Fast Refresh)
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { reactNative } from 'vite-plugin-react-native';
export default defineConfig({
plugins: [react(), reactNative()],
});兼容的 React Native 库
react-native→ 自动替换为react-native-webreact-native-safe-area-context→ 虚拟 Web 实现react-native-screens→ 虚拟 Web 实现react-native-gesture-handler→ 虚拟 Web 占位(手势在 Web 上为透传)react-native-router-dom→ 可选,安装后自动解析- 其他通过
optimizeDeps与别名支持的库:reanimated、css-interop、inline-style-prefixer 等
与社区插件能力对比
与 vite-plugin-react-native-web(下称 rnw-web)、vite-plugin-rnw(下称 rnw)对比如下。我们已具备两者核心能力,并在虚拟模块、别名、动态 optimizeDeps、RN 生态兼容上更完整。
| 能力 | rnw-web | rnw | 本插件 | |------|---------|-----|--------| | react-native → react-native-web | ✅ alias | ✅ alias | ✅ 虚拟模块(含 ReactNativeVersion) | | resolve 扩展名 .web. 优先* | ✅ | ✅ | ✅ | | define(DEV、EXPO_OS、_WORKLET 等) | ✅ | ✅ 更全(global.Error 等) | ✅ | | Vite 8 rolldownOptions | ✅ 仅 rolldown | ✅ 按版本分支 | ✅ 按版本分支(≥8 用 rolldown) | | Vite 4~7 esbuildOptions | ❌ | ✅ | ✅ | | Flow 剥离 | ✅ Rolldown 插件(code 含 @flow) | ✅ Vite 插件 + esbuild/rolldown 插件 | ✅ Rolldown 插件 + transform 对 node_modules | | treeshake 修复(css-interop / expo) | ✅ expo-modules-core | ✅ css-interop / expo | ✅ 同左 | | css-interop doctor 替换 | ❌ | ✅ | ✅ | | Reanimated webUtils ESM 转换 | ❌ | ✅(export let + require → ESM) | ✅ 仅 production 构建时转换 | | .js 当 JSX 处理 | ✅ moduleTypes | ✅ 独立插件 treat-js-as-jsx(oxc/esbuild) | ✅ 仅对 @react-native 的 .js 做 esbuild JSX | | 虚拟模块 | ❌ | ❌ | ✅ safe-area / screens / gesture-handler / openURLInBrowser | | react-native 补 ReactNativeVersion | ❌ | ❌ | ✅ | | optimizeDeps.include | ✅ 固定 ['react-native-web'] | ✅ 未显式列 | ✅ 按项目 package.json 动态,避免未安装包报错 | | resolve 别名 | ✅ 仅 react-native | ✅ 仅 react-native | ✅ react-native 子路径、router-dom、inline-style-prefixer、css-in-js-utils、Libraries/EventEmitter | | require(./assets/...) → import | ❌ | ❌ | ✅ 对 @react-native 等 | | 内置 @vitejs/plugin-react | ❌ | ✅ 一并返回 | ❌ 用户自加,更灵活 | | commonjs 插件 | ❌ | ✅ | ❌ | | 可选 react-native-router-dom | ❌ | ❌ | ✅ 安装则解析并参与预构建 |
结论:本插件在「react-native → web」基础能力上与 rnw-web / rnw 对齐,并额外提供:虚拟模块、ReactNativeVersion、动态 optimizeDeps.include、更多 resolve 别名、require(assets)→import、@react-native 的 Flow+JSX 处理;Reanimated webUtils 在 production 构建时自动将 export let + try/catch + require 转为 ESM,与 rnw 行为一致。
业界方案与兼容性说明
有没有「完美方案」?
- 官方路线:Expo 当前推荐用 Metro 打 Web(
npx expo export --platform web),与 RN 同一套构建,兼容性最好、踩坑最少。 - Vite 路线:社区方案(本插件、vite-plugin-react-native-web、vite-plugin-rnw 等),优势是 Vite 的 dev/构建速度和生态,代价是 RN 生态里 CJS/Flow/require 等需要逐类兼容,没有一家能保证「所有 RN 库零配置」。
- 本插件的策略:在参考上述社区插件的基础上,对已遇到的问题做虚拟模块、resolve 别名、transform 三类修补;新引入的库若报错,可按同一套路扩展(见下方兼容表与「新库报错怎么办」)。
常见库兼容情况(你可能会用到的)
| 库 | 本插件支持 | 说明 | |----|------------|------| | react-native-safe-area-context | ✅ 虚拟模块 | Web 下提供 SafeAreaProvider / useSafeAreaInsets 等占位 | | react-native-screens | ✅ 虚拟模块 | Web 下 Screen / ScreenContainer 等占位 | | react-native-gesture-handler | ✅ 虚拟模块 | Web 下 GestureHandlerRootView / GestureDetector 占位 | | react-native-router-dom | ✅ 别名 + 预构建 | 安装后自动解析,可选 | | react-native-reanimated | ✅ 已处理 | 有 Web 版;production 构建时自动转换 webUtils 的 export let + require 为 ESM | | react-native-svg | ✅ 一般可用 | 官方有 Web 支持,多数情况直接用;遇错再 resolve / transpile | | react-native-fetch-xhr / react-native-hox / react-native-i18njs / react-native-system-ui | ✅ 一般可用 | 纯 JS 或 polyfill,无内置专门处理也多能跑;遇错按下方「新库报错怎么办」补 | | react-native-localize | ⚠️ 需自建占位 | Web 无原生 API,需自建虚拟模块或 stub(插件未内置) | | @react-native/new-app-screen 等 | ✅ 已处理 | Flow/JSX/require(assets)/openURLInBrowser 等已做兼容 |
- ✅:插件内已有专门处理,或该库在 Web 上多数情况可直接用;遇错按「新库报错怎么办」三类套路补即可。
- ⚠️:仅 react-native-localize 等依赖原生能力的库需在 Web 上自建占位,其余均属「已覆盖」。
Demo 验证:仓库内 demo/ 已引入上表所列库(含 new-app-screen、safe-area、screens、gesture-handler、router-dom、reanimated、svg、localize、fetch-xhr、hox、i18njs、system-ui),并参与构建。在项目根目录执行:
cd demo && npm install && npm run build通过即表示上述库在当前插件下可正常打包;开发态可用 npm run dev 验证。
Demo 运行时的控制台告警说明(不影响功能,可忽略或按下方在依赖库中修复):
| 告警 | 原因 | 处理方式 |
|------|------|----------|
| Got a component with the name 'le' for the screen '/' | react-native-router-dom 内部传给 React Navigation 的 Screen 的渲染组件在打包后被压缩成短名 le,React Navigation 要求组件名首字母大写。 | 在 react-native-router-dom 源码中,找到传给 Screen 的 component(负责渲染 route.element 的那层包装组件),为其设置 displayName = 'RouteScreen'(或任意大写开头的名字)后重新构建即可消除。 |
| props.pointerEvents is deprecated. Use style.pointerEvents | 来自 React Navigation 或 react-native 的弃用提示,某处把 pointerEvents 作为 prop 传递而非放在 style 里。 | 需在 @react-navigation 或 react-native 依赖中按官方迁移方式改为 style.pointerEvents,或等待依赖库发版修复。 |
新库报错怎么办?
- 缺导出 / 找不到模块 → 在
src/virtuals.ts为该模块或路径做虚拟实现(参考openURLInBrowser、ReactNativeVersion)。 - CJS default 报错(xxx.default is not a function) → 在
src/config.ts的buildResolveAlias里为该包的lib/或具体路径做别名到es/(参考 inline-style-prefixer、css-in-js-utils)。 - Flow / JSX 在 .js 里 / require is not defined → 在
src/index.ts的 transform 里扩展:Flow 剥离、对含 JSX 的 .js 用 esbuild 编译、require('./assets/...')转 import(参考 @react-native/new-app-screen)。
按上述三类处理,大部分 RN 库在 Web 上的报错都能系统性地修掉,而不是「永远在救火」。
Vite 版本
- Vite 4.x / 5.x / 6.x / 7.x / 8.x
- 仓库内
demo/已在 Vite 6、7、8 下验证通过(npm run build);开发态npm run dev可本地自测。
工作原理简述
- 别名:
react-native→react-native-web,以及 EventEmitter、inline-style-prefixer 等路径。 - 虚拟模块:对 safe-area-context、screens、gesture-handler 提供 Web 实现或占位,无需安装对应 native 包即可跑 Web。
- 扩展名:优先解析
.web.mjs、.web.js、.web.ts、.web.tsx、.web.jsx。 - 构建与预构建:commonjs 兼容、依赖预构建列表与用户配置合并;可选路由包仅在已安装时加入。
开发
npm install
npm run build许可证
ISC
参与贡献
- Fork 本仓库
- 新建
Feat_xxx分支 - 提交代码并新建 Pull Request
