react-native - 使用 react-native-web 在 create-react-app 中处理第 3 方
问题描述
我们正在尝试在移动端(react-native)和网络端(create-react-app)使用相同的 React 组件。
多亏了react-native-web(下面的配置),到目前为止它运行得很好。
然而,我们在 react-native 项目中广泛使用的react-native-vector-icons不能与react-native-web一起编译。这意味着任何使用带有矢量图标的组件的组件也需要特定的 Web 版本。拥有特定于 Web 的组件版本会影响维护。
有没有一种已知的方法,无需弹出 create-react-app 配置,来处理web中的 react-native-vector-icons等 3rd 方?
import {createIconSetFromIcoMoon} from "react-native-vector-icons";
import Font from './Font.json';
export default createIconSetFromIcoMoon(UbeyaFont);
到目前为止我们已经想到的事情: 我们目前正在研究两个想法:
基于环境的导入:
# Pseudo code: # if mobile import this, otherwise import that.
我们不确定这种动态导入是否可行
注入到node_modules/react-scripts 的Webpack 配置。不优雅,但我们有一个 gulp 手表,我们可以确保配置始终存在。
任何想法或想法都会受到赞赏。
配置: 我们构建了一个新的私有 NPM 包,其中包含所有 React 组件,并且通过使用gulp watch将包复制到移动和 Web 项目,我们省去了在开发过程中不断发布 npm和yarning的麻烦(Webstorm 的唯一缺点索引过程)。
解决方案
我们最终使用 gulp 脚本来覆盖 webpack。阶段是:
1)构建替换包
我们为每个React Native 3rd 方构建了一个 web 版本。对于react-native-vector-icons,结果非常简单:
import React from 'react';
export const Icon = (props) => <div className="material-icons"
style={{color:props.color}}>
{props.name}
</div>;
export default Icon;
2)调整Webpack配置
使用 gulp 我们覆盖create-react-app webpack 配置:
resolve: {
modules: ...
alias: {
"babel-runtime": path.dirname(
require.resolve("babel-runtime/package.json")
),
"react-native": "@ourcompany/react-native-web",
"react-native-vector-icons": "@ourcompany/react-native-vector-icons",
...
gulp 任务脚本:
gulp.task("copyWebpack", function() {
return gulp
.src(["package.json", "src/_webpack/*.js"])
.pipe(
gulp.dest(
path.resolve(pathWeb + "/node_modules/react-scripts/config")
)
);
});
笔记:
- 弹出 create-react-app 的配置更简洁,但这意味着您需要维护配置,我们更喜欢保留配置并在构建过程中覆盖它。
- 你会注意到我们已经覆盖了 react-native-web 本身。在下一个可选步骤中了解更多信息。
3) 扩展 react-native-web (可选)
如果您正在使用react-native-web尚不支持的组件,您需要为它们构建包并扩展react-native-web以便您的 Web 版本可以工作。只需创建一个新包@yourcompany/react-native-web并生成一个index.js ,其中导入react-native-web中确实存在的组件并引用您构建的组件。请注意,当我们构建项目时,react-native-web没有 FlatList 或 SectionList,而现在(2018 年 10 月)它两者都有(Modal 仍然缺失 :-))。
import {
StyleSheet as _StyleSheet,
View as _View,
Text as _Text,
Image as _Image,
I18nManager as _I18nManager,
AsyncStorage as _AsyncStorage,
Platform as _Platform,
Linking as _Linking,
ActivityIndicator as _ActivityIndicator,
ListView as _ListView,
Modal as _Modal,
Picker as _Picker,
RefreshControl as _RefreshControl,
TextInput as _TextInput,
Touchable as _Touchable,
TouchableHighlight as _TouchableHighlight,
TouchableNativeFeedback as _TouchableNativeFeedback,
TouchableOpacity as _TouchableOpacity,
TouchableWithoutFeedback as _TouchableWithoutFeedback,
Dimensions as _Dimensions,
Animated as _Animated,
ScrollView as _ScrollView,
SafeAreaView as _SafeAreaView,
BackHandler as _BackHandler,
Switch as _Switch,
NetInfo as _NetInfo,
AppState as _AppState,
ColorPropType as _ColorPropType,
} from 'react-native-web';
import {SectionList as _SectionList} from './SectionList';
import {FlatList as _FlatList} from './FlatList';
import {Alert as _Alert} from './Alert';
import {WebView as _WebView} from './WebView';
import {Share as _Share} from './Share';
import {PermissionsAndroid as _PermissionsAndroid} from './PermissionsAndroid';
import {ActionSheetIOS as _ActionSheetIOS} from './ActionSheetIOS';
import {ToastAndroid as _ToastAndroid} from './ToastAndroid';
export const StyleSheet = _StyleSheet;
export const View = _View;
export const Text = _Text;
export const Image = _Image;
export const I18nManager = _I18nManager;
export const AsyncStorage = _AsyncStorage;
export const Platform = _Platform;
export const Linking = _Linking;
export const ActivityIndicator = _ActivityIndicator;
export const ListView = _ListView;
export const Modal = _Modal;
export const Picker = _Picker;
export const RefreshControl = _RefreshControl;
export const TextInput = _TextInput;
export const Touchable = _Touchable;
export const TouchableHighlight = _TouchableHighlight;
export const TouchableNativeFeedback = _TouchableNativeFeedback;
export const TouchableOpacity = _TouchableOpacity;
export const TouchableWithoutFeedback = _TouchableWithoutFeedback;
export const Dimensions = _Dimensions;
export const Animated = _Animated;
export const ScrollView = _ScrollView;
export const SafeAreaView = _SafeAreaView;
export const BackHandler = _BackHandler;
export const Switch = _Switch;
export const NetInfo = _NetInfo;
export const AppState = _AppState;
export const Alert = _Alert;
export const Share = _Share;
export const WebView = _WebView;
export const PermissionsAndroid = _PermissionsAndroid;
export const ActionSheetIOS = _ActionSheetIOS;
export const ToastAndroid = _ToastAndroid;
export const SectionList = _SectionList;
export const FlatList = _FlatList;
export const ColorPropType = _ColorPropType;
推荐阅读
- python - 为什么'!='和'=='在python中的while或for循环中不起作用
- java - Hibernate 将 REFCURSOR 返回类型解析为 null,抛出 Invalid column type: 2012
- ruby-on-rails - 发布请求上的 FastJsonapi ID 必填字段,无法处理的实体?
- node.js - Node 中的 Promise 池
- webpack-4 - Autoprefixer 不添加供应商前缀
- c - 捕捉到意外信号:SIGSEGV (11)。无效的内存访问
- database - IP 地址数据类型
- python - 无法使用 gunicorn 运行(Python)瓶子应用程序
- tensorflow - 如何减少 TPU 空闲时间?
- python - 如何查看 geopandas 数据框中的所有列?