React-Native-Web编译报错,如何为Web和移动端配置不同的依赖库?
解决方案
完全可以针对Web端和移动端使用不同的依赖/组件实现,这是React Native跨端适配的常规操作,你遇到的报错本质是两类问题:一是部分React Native原生库没有提供Web侧实现,二是Webpack默认不会转译node_modules下的Flow/TS/JSX语法,可按以下步骤处理:
第一步:修复Webpack转译配置
你使用的是Expo环境,先配置Webpack转译规则处理语法报错:
- 安装Expo Webpack配置依赖:
yarn add @expo/webpack-config -D - 项目根目录新建
webpack.config.js,内容如下:
const createExpoWebpackConfigAsync = require('@expo/webpack-config'); module.exports = async function (env, argv) { const config = await createExpoWebpackConfigAsync({ ...env, babel: { dangerouslyAddModulePathsToTranspile: [ // 把所有报错的node_modules包添加到这里 '@react-native-community', '@sentry/react-native', 'react-native-webview', 'react-native-pdf', 'react-native-media-controls', 'react-native-skeleton-placeholder' ] } }, argv); return config; };
第二步:配置端侧差异化依赖
有两种常用方案实现Web/移动端依赖分离:
方案1:文件扩展名自动匹配
React Native打包器(Metro)和Webpack都会自动识别带平台后缀的文件:
- 移动端专用文件命名为
xxx.native.tsx/xxx.native.js - Web端专用文件命名为
xxx.web.tsx/xxx.web.js - 业务代码引入时直接写
import xxx from './xxx',打包时会自动根据目标平台加载对应文件
比如你用到的媒体控制组件,移动端继续用react-native-media-controls,Web端自己实现一个基于原生video标签的控制组件,按上述规则命名即可无缝切换。
方案2:Webpack别名全局替换
针对不想修改业务代码的场景,直接在Webpack配置里把不兼容Web的原生库替换为Web兼容版本,修改上述webpack.config.js添加alias配置:
const createExpoWebpackConfigAsync = require('@expo/webpack-config'); const path = require('path'); module.exports = async function (env, argv) { const config = await createExpoWebpackConfigAsync({ ...env, babel: { dangerouslyAddModulePathsToTranspile: [ '@react-native-community', '@sentry/react-native', 'react-native-webview', 'react-native-pdf', 'react-native-media-controls', 'react-native-skeleton-placeholder' ] } }, argv); config.resolve.alias = { ...config.resolve.alias, // 把原生依赖替换为web兼容版本 '@react-native-community/progress-view': 'react-native-progress', '@react-native-community/masked-view': '@react-native-masked-view/masked-view', '@sentry/react-native': '@sentry/react', 'react-native-webview': path.resolve(__dirname, 'src/components/WebView.web.tsx'), 'react-native-pdf': path.resolve(__dirname, 'src/components/PdfViewer.web.tsx') }; return config; };
常见报错库的适配方案
@react-native-community/progress-view/masked-view:最新官方版本已经自带Web实现,直接升级到最新版即可react-native-pdf:Web端直接用原生<embed>标签加载PDF,或替换为react-pdf库react-native-webview:Web端直接用iframe封装实现即可react-native-media-controls:Web端直接启用video标签原生controls属性,不需要额外引入组件
内容的提问来源于stack exchange,提问作者Rahul Vyas
相关产品推荐
相关产品推荐

