webstorm打包rn项目_换换项目三端化的小试牛刀

换换项目三端化的小试牛刀

背景

在换换项目列表页、详情页用React-native实现了Android、iOS的基础上,要继续上web端,为节省开发成本,本着一套代码三端使用的原则,并且在此之前我们的RN小团队经过调研,基于以上业务的基础上并产出了一套WubaRN-web库,以支持三端化的需求,因此也为该需求的接入奠定了基础。

方案

React-native + React-native-web + WubaRN-web。

968262662df37637a70d765cbdaef73b.png

这里首先看下WubaRN-web的主要工作,因为React-native代码编译出来的bundle.js文件目前只能在App里运行,无法直接在web上运行。那么要生成可以直接在web运行的js需要一套react-native-web库,通过webpack将react-native库替换为react-native-web库进行打包,做下如下配置: 1. 在web/configs/webpack.config.js文件里

{
    resolve: {
        alias: { 'react-native': 'react-native-web' },
    },
}

也就是把指向react-native的地方指向react-native-web
2. 针对react-native-web提供的API有些不能满足业务需求,在自定义文件中将不满足需求的API组件等替换为自定义的实现,如: 

 /src/lib/react-native-web/index.js 

import ReactNative, {
  // top-level API
  createElement,
  findNodeHandle,
  render,
  ...
  // Text,
  ...
  PointPropType
} from 'react-native-web';

import Text from './Text'
ReactNative.Text = Text;
import DeviceEventEmitter from './DeviceEventEmitter';
ReactNative.DeviceEventEmitter = DeviceEventEmitter;
...
export {
  // top-level API
  createElement,
  findNodeHandle,
  render,
  ...
  Text,
  ...
  PointPropType
};
export default ReactNative;

如上代码,直接转换的Text控件,不能满足我们的业务需求,所以需要我们引入我们自定义的 

7b080a56bd2479aa8a2e27f16c3794b6.png

  1. RN页面有依赖NativeModule的功能以及组件,可以由以下方式方便的添加自定义组件,modules.config.js配置文件 

    //自定义API配置,根据NativeModules调用的
    const WBWebModulesConfig = {
      WBShare: require('./WBShare').default, /** 分享 */
      WBUserLog: require('./WBUserLog').default, /** 埋点*/
      WBLocation: require('./WBLocation').default,/** 定位*/
      WBInitialParams: require('./WBInitialParams').default,/** 初始化参数 */
      WBToast: require('./WBToast').default, /** Toast提示 */
      WBLoadingBar: require('./WBLoadingBar').default, 
    };
    //自定义view配置,根据requireNativeComponent调用的
    const WBCustomWebViewsConfig = {  
        WBErrorView: require('./WBErrorView').default
    };
    exports.WBWebModulesConfig = WBWebModulesConfig;
    exports.WBCustomWebViewsConfig = WBCustomWebViewsConfig; 

    入口index.js文件添加注册 

    import {NativeModules} from 'react-native-web'
    import {WBComponentsConfig} from './lib/react-native-web/requireNativeComponent'
    import {WBWebModulesConfig,WBCustomWebViewsConfig} from '../wb_modules/modules.config';
    //往NativeModules中注册自定义API
    Object.keys(WBWebModulesConfig).forEach(function (key){
    NativeModules[key] = WBWebModulesConfig[key];
    });
    //往requireNativeComponent中注册自定义View组件
    Object.keys(WBCustomWebViewsConfig).forEach(function (key){
    WBComponentsConfig[key] = WBCustomWebViewsConfig[key];
    });

    webpack配置文件如下:

     resolve: {
        alias: {
            'react-native':path.resolve(__dirname, '../src/lib/react-native-web/index.js'),
        }
      }

    以上主要是WubaRN-web的主要工作,接下来,看业务层如何接入。

    实现

    接入流程很简单,直接导入wubaRN-web库即可
    1.在换换列表、详情页RN项目的基础上引入wubaRN-web库,所以项目结构如下: 

    ---| root
    ---|    |-node_modules
    ---|    |-src //存放共用RN代码
    ---|         |-App
    ---|             |-index.js
    ---|    |-web //web的相关配置
    ---|         |-configs
    ---|             |-webpack.config.js //webpack打包配置文件
    ---|         |-node_modules
    ---|         |-src
    ---|             |-index.js
    ---|         |-package.json //针对web的依赖配置文件 基于react-

wubaRN-web就是以上的web目录里面的东西。 2.运行项目 * cd web 进入web目录 * npm start 启动服务 * 浏览器输入 http://localhost:3000/

ede895ed05d84f243300fbcbadc61621.png

问题

  1. tab栏没法固定

75aee6a5fef98bce8b717fcf4ed84c49.png

解决(业务层):需要在style中加入以下属性:

position: 'fixed',
top: 0,
left: 0,
zIndex: 8,

2.FlatList的onRefresh、onEndReached等相关属性不起作用解决(业务层):直接把FlatList组件替换为普通的View,并监听Scroll方法及解析数据拼装item等方法

IS_WEB ?
  
  :
window.addEventListener('scroll', function () {
      ...此处省略 滑动距离的判断
      that.store.loadMore();
}, false);
....

3.切换tab时,列表页没有自定滚动到最顶部原因:RN端使用flatlist的scrollToIndex()实现,普通的View没有该属性解决(业务层):使用window.scrollBy()处理

4.列表页滑动时,误点击进入详情页原因:列表页item最外层使用TouchableOpacity实现,在onPress执行点击,当直接使用web库转换后,容易出发它的点击事件。解决(业务层):把TouchableOpacity替换收到替换为标签来处理,这样就避免了误点击问题。 

5.调用naive的API没法直接使用,比如: * WBAPP.initialParams(‘WB_JUMPER’)获取跳转协议携带的参数原因:web端跳转方式与RN端不样,跳转协议也一样解决(wubaRN-web库):下兼容处理,从跳转的URL里获取

 initialParams(action, callback) {
         setTimeout(() => {
         var json = searchToObject(location.search);
         callback({
             'WB_JUMPER': {"params":{},"content":json}
      })
    })
  },
  • WBAPP.getLocation(localData) 获取native 定位SDK返回的参数原因:web无法使用native提供的定位SDK解决(wubaRN-web库):引入web端的定位SDK

    getLocation: function (callback) {
    if (typeof callback === 'function') {
      var geolocation = new BMap.Geolocation();
      geolocation.getCurrentPosition(function (r) {
        if (r && r.point) {
          // // 创建地理编码实例    
          var myGeo = new BMap.Geocoder();
          // 根据坐标得到地址描述 
          myGeo.getLocation(new BMap.Point(r.point.lng, r.point.lat), function (result) {
            if (result) {
              let business = result.business;
              callback && callback({
                "statusCode": 0,
                "content": {
                  "lon": r.point.lng,
                  "lat": r.point.lat,
                  "businessName": business,
                }
              })
            } 
    }
  • WBAPP.setWebLog()调用native的埋点框架原因:APP端与M端埋点框架不一样解决(wubaRN-web库):兼容转换为M端格式的埋点

    export  function setWebLog({pagetype = '',actiontype = '',cate = '',  paramsArray,extraParams  }) {
    let protocol = location.protocol || 'http:';//协议头,由页面协议确定
    let trackURL = JSON.stringify({
        page: actiontype,
        cate: cate,
        area: '',
        pagetype: pagetype,
        ...extraParams,
        ...paramsArray
    })
    ...
    }

6.详情页返回列表页,列表没有保留现场原因:列表页,详情页分别都是单独的一个js文件,所以当返回列表页的时候,浏览器会重新执行一遍js文件的流程,以至没有保留现场,而重新加载了。解决(业务层):跳转时,使用sessionStorage缓存当前页面的item数据,当前显示的tab等相关数据以及各标识,下次加载时,优先判断下。

 {
    sessionStorage.setItem(comStore.BACK_FROM_JUMP, 1);
    sessionStorage.setItem(comStore.MORE_URL, moreUrl);
    sessionStorage.setItem(comStore.LIST_CHOOSE, listchoose);
    }
}>

7.网络请求跨域问题原因:跨域名请求服务器解决(业务层):$.ajax处理
......
还有一些各式各样的问题,这里就不一一列举出来了,而且目前主要是在业务层处理的。

总结

因为WubaRN-web开始就是以换换需求为技术背景产出的,所以前期解决了部分问题,但是真正接入时,还是还有各式各样的问题存在,挖坑填坑的方式直到到达上线要求,其中也走了不少弯路,不过整体来看,确实减少了开发量,大概评估了下,该需求如果纯web端开发的话,假如10天的工作量,直接转换加上解决以上问题,一共用了5天左右,如果后期WubaRN-web把以上问题中业务层处理的公共的部分都解决掉了话,相信开发量会骤减。 最后,感谢前期,@蒋宏伟、@朴惠姝、@于卫国的支持。

参考

http://wxc.58corp.com/pages/viewpage.action?pageId=25730228

e67d590b8931125a6fe6ac66e69a1d29.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值