什么是三端同构?刚接触rn开发的同学可能不太了解,我简单介绍一下。三个终端是指Android、IOS、H5。rn本身就是一个跨平台的框架。为了让RN在不改动代码的情况下兼容H5,只需要引入一些库,配置一些细节即可。本模板使用当前react-native@0.6x、react-navigation@5.x新版本搭建ts开发环境。新版本相关库部分API与旧版本不兼容,请勿随意更改主版本!无论是刚入门RN的初学者,还是老版本RN的熟练用户,都可以轻松上手模板源码构建过程(从零开始)1.安装RN并配置开发环境根据官网,对客户端开发前端不熟悉的可以选择沙箱环境。不过还是建议一步步安装客户端环境,毕竟现在是跨平台时代。2.使用react-native生成typescript模板首先,新版RN不再使用react-native-cli,也就是说我们不需要全局安装任何包。只要你的npm版本是5.2+,就可以使用npx命令(npx介绍)。npxreact-nativeinitMyApp--templatereact-native-template-typescriptnpxgeneratesrnfortstemplate,安装完成后,这是一个官方可运行的RN项目,接下来我们将修改这个模板3.配置package.json中为了使用新版@react-navigationv5构建一个完全可用的RN开发项目和我们要做的三端同构,需要添加一些npm依赖包。"dependencies":{//...模板附带的包//..."@react-native-community/async-storage":"1.9.0",//等同于localStorage(可选)"@react-native-community/masked-view":"0.1.9",//路由所需的包(必填)"@react-navigation/stack":"5.2.10",//路由所需的包(必填)“react”:“16.11.0”,“react-dom”:“16.11.0”,“react-native”:“0.62.2”,“react-native-gesture-handler”:“1.6.0”,//路由所需的包,原生手势系统(必填)"react-native-reanimated":"^1.8.0",//路由所需的包(必填)"react-native-safe-area-context":"0.7.3",//路由所需的包(必填)"react-native-screens":"^2.3.0",//路由所需的包(必填)"react-native-webview":"8.0.0",//RN打开webView容器,原生调用(可选)"react-redux":"5.0.7","redux":"4.0.0","redux-thunk":"2.3.0"},"devDependencies":{//...模板自带的包//..."@babel/plugin-transform-runtime":"^7.9.0",//babel的插件包(必填)"@babel/preset-typescript":"^7.9.0",//babel编译ts(必填)"@react-navigation/core":"3.4.2",//rn路由在H5传输线路核心包(必填)"@react-navigation/web":"1.0.0-alpha.8",//H5中运行的rn路由核心包(必填)"babel-loader":"^8.1.0",//webpack加载器(必需)"file-loader":"3.0.1",//webpack加载器(必需)"html-webpack-plugin":"^4.2.0",//webpackplugin(必填)"react-native-web":"0.12.2",//rn组件映射到WEBdom(必填)"webpack":"4.42.1",//打包rn项目到h5(必填)"webpack-cli":"3.3.2",//将rn项目打包到h5(必填)"webpack-dev-server":"3.5.1"//将rn项目调试到h5(必填)},install该装的都不要错过,我建议Stud4.配置webpack和文件入口,首先创建一个index.html文件作为H5打包模板根目录,index.ts是RN原生打包的入口,以及新建一个index.web.ts作为H5打包入口,注意在webpack中添加resolve:{extensions:['.web.ts','.web.tsx','.ts','.tsx','.js','.jsx'],alias:{'react-native$':'react-native-web'}},extensions配置的目的是让我们的项目可以写两个不同后缀的文件xx从'./xx'导入XX.web.ts,xx.ts一个是给RN打包成native,一个是给webpack打包成H5,用于不同平台代码的定制化开发,在路由上用处极大。.web.ts必须配置在.ts前面,这样webpack才能先找到属于H5的文件并打包。另外,alias是将react-native整个库的组件映射到react-native-web。其实这个库的原理就是为RN的每个组件写好对应的dom,然后传入props。因为也可以自己扩展,所以有些原生组件是react-native-web中没有的,比如开头提到的webView。{test:/\.(js|jsx|ts|tsx)$/,使用:[{loader:'babel-loader',options:{cacheDirectory:false,presets:['module:metro-react-native-babel-preset','@babel/preset-typescript'],plugins:['@babel/plugin-transform-runtime']}}],exclude:/node_modules/}其次,配置babel-loader编译ts,特别是这里注意:不能用ts-loader编译!因为我们在tsconfig.json文件中配置的jsx被识别为react-native,用于编译到客户端,但实际上我们将其代理成一个dom元素,打包会产生冲突,导致loader编译错误。解决方法是直接使用babel-loader配置编译TS,生成sourcemap5。配置React-navigation,ReduxRedux状态管理和普通react一样,也可以使用其他库。毕竟状态管理不涉及渲染。主要讲解一下RN的路由库React-navigation,各个版本的API差异很大,V5版本将API拆分成多组@react-navigation/,路由配置选项有很多,我这里提供一个://router.tsimport'react-native-gesture-handler';从'react'导入React;从'react-redux'导入{connect};从'@react-native-community/async-storage'导入AsyncStorage;从'@react-navigation/native'导入{InitialState,useLinking,NavigationContainerRef,NavigationContainer,DefaultTheme,DarkTheme};从'@react-navigation/stack'导入{createStackNavigator,HeaderStyleInterpolators};从'./config'导入路线;类型RootDrawerParamList={[key:string]:any;};constStack=createStackNavigator
