首页 > 解决方案 > 使用 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);

到目前为止我们已经想到的事情: 我们目前正在研究两个想法:

任何想法或想法都会受到赞赏。

配置: 我们构建了一个新的私有 NPM 包,其中包含所有 React 组件,并且通过使用gulp watch将包复制到移动和 Web 项目,我们省去了在开发过程中不断发布 npmyarning的麻烦(Webstorm 的唯一缺点索引过程)。

标签: react-nativecreate-react-appreact-native-web

解决方案


我们最终使用 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;

推荐阅读