You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过React Native WebView加载本地dist目录React Web应用

React Native WebView加载本地构建dist静态资源方案

你提到的Metro打包静态资源加载的思路完全可行,以下是3种可落地的实现方式,适配Monorepo架构下React+React Native的代码复用场景:


方案1:Metro托管静态资源(推荐,适配成本最低)

这是最适配Monorepo架构的方案,不需要修改原生工程配置,配置一次后web端构建完产物可以直接被RN侧引用。

  1. 调整Web端构建配置
    把Web应用构建工具的资源公共路径改成相对路径,避免本地file协议加载时资源路径404:

    • Vite项目:配置项base: './'
    • Webpack/Rspack项目:配置项publicPath: './'
      构建完成后检查dist/index.html内的资源引用,确保app.js/app.css等资源是./xxx的相对路径格式。
  2. 配置Metro识别Web静态资源
    在mobile工程根目录的metro.config.js中添加web静态资源后缀,让Metro把这些文件识别为静态资产打包,不要按RN业务模块解析:

    const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
    const defaultConfig = getDefaultConfig(__dirname);
    
    const config = {
      resolver: {
        assetExts: [
          ...defaultConfig.resolver.assetExts,
          'html', 'htm', 'css', 'svg', 'woff', 'woff2', 'ttf'
        ]
      }
    };
    
    module.exports = mergeConfig(defaultConfig, config);
    

    Monorepo场景下可以加个简单的构建脚本,web端执行build生成dist后,自动把dist目录拷贝/软链到mobile工程的固定路径(比如src/web-dist/),不需要手动同步资源。

  3. WebView组件加载本地入口文件
    直接用require引用dist下的index.html,不需要手动拼接file协议路径,自动兼容双平台:

    import { WebView } from 'react-native-webview';
    
    export default function EmbeddedWebPage() {
      return (
        <WebView
          source={require('./src/web-dist/index.html')}
          originWhitelist={['*']}
          allowFileAccess={true}
          javaScriptEnabled={true}
          domStorageEnabled={true}
        />
      );
    }
    

方案2:内联HTML字符串注入(仅适合轻量单文件场景)

如果web构建产物是单文件、没有懒加载子资源/拆分chunk,可以直接把JS、CSS内容内联到HTML字符串里,通过WebView的html属性传入,也就是你提到的Metro打包资源后拼接HTML的思路:

const embeddedHtml = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>${require('./src/web-dist/app.css')}</style>
</head>
<body>
  <div id="root"></div>
  <script>${require('./src/web-dist/app.js')}</script>
</body>
</html>
`;

// 组件使用
<WebView
  source={{ html: embeddedHtml, baseUrl: '' }}
  originWhitelist={['*']}
  javaScriptEnabled={true}
/>

注意:该方案不支持懒加载资源、路由跳转等场景,大体积JS内联会增加内存占用,首屏加载速度慢,仅适合非常简单的静态页面。


方案3:原生工程托管静态资源(适合大体积Web产物)

如果web端构建产物体积超过10M,用Metro打包会拖慢RN热更新速度,可以把dist目录直接放到原生工程的静态资源目录下,通过file协议加载:

  • Android端:把dist目录拷贝到android/app/src/main/assets/web-dist/路径下,加载时uri填file:///android_asset/web-dist/index.html
  • iOS端:把dist目录拖入Xcode工程,选择Create folder references加入主Bundle,通过原生Bundle API获取资源路径后拼接file协议地址传入
    该方案需要写脚本自动同步dist产物到原生目录,配置成本较高,适合web产物体积大的场景。

常见踩坑点

  • Android 9及以上版本WebView默认禁止访问本地文件,必须开启allowFileAccess={true}属性
  • Android端默认关闭DOM存储能力,如果web端用到localStorage/IndexedDB,必须开启domStorageEnabled={true}
  • 如果web端有接口请求,需要配置mixedContentMode="compatibility"避免http/https混合内容拦截
  • 不要用手动拼接的绝对file路径加载资源,不同版本系统、不同调试模式下路径会有差异,优先用require引用或者原生API获取资源路径

内容的提问来源于stack exchange,提问作者Vardan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:57:13