一起成长,跨平台开发是为了增加代码复用

摘要腾讯开源了移动端Web组件化框架Omi,相对于
react,代码尺寸更小,速度更快。目前接入和正在接入的项目有:
腾讯课堂、QQ群、兴趣部落、QQ空间玩吧等。基本介绍Omi 由 Preact + Scoped
CSS + Store System + Native Support in 3kb javascript
等组件组成。由于有段时间 react native
授权协议问题,内部的rn急需替代品。所以我们自研了 plato 代替
rn。做了一些权衡之后,我决定基于 preact 二次开发,把 preact 的 dom
模块更加抽象了针对浏览器和向 native 发指令。相对于 react,preact
代码尺寸更小,速度更快,jsx里的约定更贴合web的习惯 ,通过 preact compat
几乎百分百兼容react,在一些方面还在走在 react 前面 ,preact
没有自己实现事件体系,内部直接 addEventListener
实现,这也是性能出众和尺度极小的原因之一。风格和优势Omi 从 3.0 开始基于
preact 二次开发,完全可以共享 preact 和 react
的生态,也有了自己独特的风格和优势:超小的尺寸和超快的速度兼容
React/Preact/Omi APIScoped CSS, 让你的 CSS 选择器更加简单每个组件都有
update 方法,当然你也可以继续 setStateStore system,
内置的,不需要依赖任何库创建网站无需任何配置的脚手架工具 omi-cli
(相当于 create-react-app 多页面版本,也拥有有 ssr
的模板)想要的一切都有:Server side render, ES6+, JSX, VDOM, React
DevTools, HMR …Native 支持目前接入和正在接入的项目有:
腾讯课堂、QQ群、兴趣部落、QQ空间玩吧等。开源地址详见:

2.开源app:

  • 官方演示App
    https://github.com/facebook/react-native/tree/master/Examples

  • Facebook F8 App
    https://github.com/fbsamples/f8app

  • GitHub
    Popular(一个用来查看GitHub最受欢迎与最热项目的App)已上架
    https://github.com/crazycodeboy/GitHubPopular

  • 奇舞周刊 iOS 版(上架应用)
    https://github.com/fakefish/Weekly75

  • react-native-dribbble-app
    https://github.com/catalinmiron/react-native-dribbble-app

  • Gank.io客户端
    https://github.com/Bob1993/React-Native-Gank

  • Mdcc客户端(优质)
    https://github.com/Bob1993/mdcc-client

  • Leanote for iOS(云笔记)
    https://github.com/leanote/leanote-ios-rn

ReactNativeRubyChina
https://github.com/henter/ReactNativeRubyChina

  • HackerNews-React-Native
    https://github.com/iSimar/HackerNews-React-Native

  • React-Native新闻客户端
    https://github.com/tabalt/ReactNativeNews

  • newswatch(新闻客户端)
    https://github.com/bradoyler/newswatch-react-native

  • buyscreen(购买页面)
    https://github.com/appintheair/react-native-buyscreen

  • V2EX客户端
    https://github.com/samuel1112/v2er

  • react-native-todo
    https://github.com/joemaddalone/react-native-todo

  • react-native-beer
    https://github.com/muratsu/react-native-beer

  • react-native-stars
    https://github.com/86/react-native-stars

  • 模仿天猫首页的app
    https://github.com/hugohua/react-native-demo

  • ReactNativeChess
    https://github.com/csarsam/ReactNativeChess

  • react native 编写的音乐软件
    https://github.com/Johnqing/miumiu

  • react-native-pokedex
    https://github.com/ababol/react-native-pokedex

  • CNode-React-Native
    https://github.com/SFantasy/CNode-React-Native

  • 8tracks电台客户端
    https://github.com/voronianski/EightTracksReactNative

  • React-Native实现的计算器
    https://github.com/yoxisem544/Calculator-using-React-Native

  • 房产搜索app
    https://github.com/jawee/react-native-PropertyFinder

  • 知乎专栏app
    https://github.com/LeezQ/react-native-zhihu-app

  • Segmentfault 客户端
    https://github.com/fakefish/sf-react-native

  • 糗事百科app
    https://github.com/stormhouse/QiuShiReactNative

  • 孢子社区app
    https://github.com/Hi-Rube/baoz-ReactNative

  • 深JS app
    https://github.com/fraserxu/shenjs

  • Den – 房屋销售app*
    https://github.com/asamiller/den

  • Noder-cnodejs客户端
    https://github.com/soliury/noder-react-native

  • 知乎日报Android版
    https://github.com/race604/ZhiHuDaily-React-Native

  • ziliun-react-native
    https://github.com/sonnylazuardi/ziliun-react-native

  • react-native-weather-app
    https://github.com/shevawen/react-native-weather-app

  • React Native Sample App(Navigation,Flux)
    https://github.com/taskrabbit/ReactNativeSampleApp

  • TesterHome社区app
    https://github.com/qddegtya/A-ReactNative-TesterHome

  • Finance – 股票报价app
    https://github.com/7kfpun/FinanceReactNative

  • shopping – 购物app
    https://github.com/bigsui/shopping-react-native

  • zhuiyuan – 追源cms app
    https://github.com/kazaff/ZhuiYuanDemo

  • uestc-bbs-react-native – UESTC清水河畔RN客户端(with Redux)
    https://github.com/just4fun/uestc-bbs-react-native

  • react-native-nw-react-calculator(iOS/Android、Web、桌面多端)
    https://github.com/benoitvallon/react-native-nw-react-calculator

  • react-native-nba-app
    https://github.com/wwayne/react-native-nba-app

  • 开源中国的Git@OSC客户端
    http://git.oschina.net/rplees/react-native-gitosc

  • rn_bycloud 帮瀛律师端app
    https://github.com/liuchungui/rn\_bycloud

  • Reading App Write In React-Native(Studying and Programing
    https://github.com/attentiveness/reading

  • 数独 – 重拾纯粹数独的乐趣
    https://github.com/nihgwu/react-native-sudoku

  • Shop-React-Native
    https://github.com/EleTeam/Shop-React-Native

  • 掘金客户端
    https://github.com/wangdicoder/JueJinClient

  • cnblogs 客户端
    https://github.com/togayther/react-native-cnblogs

注:加粗的项目,可以重点关注一下


Songlcy

Preact是React的轻量级实现,是React比较好的替代者之一,有着体积小的优点,当然与React之间一定会存在实现上的差异,本文介绍了在
setState 方面的差异之处。

全篇内容较多,需耐心食用!

2.哪些人在用

图片 1

图片 2

上面是官方贴出的一些截图

目前我知道的一些项目:

1.蚂蚁金服
蚂蚁金服有一套开源的react组件,支持web还有rn端,这是一个可以参考的三端统一方案

2.京东
京东JDReact,也实现了三端统一的方案,这篇文章,就京东现有架构做了一些解读

图片 3


江清清

更新阶段:

export function renderComponent(component, opts, mountAll, isChild) {
  ...
  previousProps = component.prevProps || props,
  previousState = component.prevState || state,
  previousContext = component.prevContext || context,
  ...

  // if updating
  if (isUpdate) {
    component.props = previousProps;
    component.state = previousState;
    component.context = previousContext;
    if (opts!==FORCE_RENDER
      && component.shouldComponentUpdate
      && component.shouldComponentUpdate(props, state, context) === false) {
      skip = true;
    }
    else if (component.componentWillUpdate) {
      component.componentWillUpdate(props, state, context);
    }
    component.props = props;
    component.state = state;
    component.context = context;
  }
  ...
}

在更新流程前提取了旧 state,shouldComponentUpdate、componentWillUpdate
之后还原回新值,所以在 shouldComponentUpdate 生命周期中,this.props
将获取的是 prevProps,这里与 React 的逻辑并不一致。

3、Flutter

Google 出品,Dart语言,Flutter Engine引擎,响应式设计模式,原生渲染

Flutter 是谷歌2018年发布的跨平台移动UI框架。相较于本人已经在项目中使用过
react native 和 Weex,Flutter目前仅仅是简单运行过Demo,毕竟还是beta
阶段,这里更多的聊一下它的实现机制和效果。

与 react native 和 weex 的通过 Javascript 开发不同,Flutter
的编程语言是Drat,(谷歌亲儿子,据说是因为 Drat 项目组就在 Flutter
隔壁而被选上所以执行时并不需要 Javascript
引擎,但实际效果最终也通过原生渲染。

图片 4图片来源网络

如上图,Flutter 主要分为 FrameworkEngine,我们基于Framework
开发App,运行在 Engine 上。Engine 是 Flutter
的独立虚拟机,由它适配和提供跨平台支持,目前猜测 Flutter 应用程序在
Android 上,是直接运行 Engine 上
所以在是不需要Dalvik虚拟机。(这是比kotlin更彻底,抛弃JVM的纠缠?)

如下图,得益于 Engine 层,Flutter 甚至不使用移动平台的原生控件,
而是使用自己 Engine 来绘制 Widget (Flutter的显示单元),而 Dart
代码都是通过 AOT 编译为平台的原生代码,所以 Flutter 可以
直接与平台通信,不需要JS引擎的桥接。同时 Flutter 唯一要求系统提供的是
canvas,以实现UI的绘制。咦?这么想来,支持web端也没问题吧!

图片 5图片来源网络

在Flutter中,大多数东西都是widget,而widget是不可变的,仅支持一帧,并且在每一帧上不会直接更新,要更新而必须使用Widget的状态。无状态和有状态
widget
的核心特性是相同的,每一帧它们都会重新构建,有一个State对象,它可以跨帧存储状态数据并恢复它。

Flutter 上 Android 自带了 Skia,Skia是一个
2D的绘图引擎库,跨平台,所以可以被嵌入到 Flutter的 iOS SDK中,也使得
Flutter Android SDK要比 iOS SDK小很多。

这算是互相伤害的环节了吧。

类型 React Native Weex Flutter
平台实现 JavaScript JavaScript 无桥接,原生编码
引擎 JSCore JS V8 Flutter engine
核心语言 React Vue Dart
Apk大小 7.6M 10.6M 8.1M
bundle文件大小 默认单一、较大 较小、多页面可多文件 不需要
上手难度 稍高? 容易 一般
框架程度 较重 较轻
特点 适合开发整体App 适合单页面 适合开发整体App
社区 丰富,Facebook重点维护 有点残念,托管apache 刚刚出道小鲜肉,拥护者众多
支持 Android、IOS Android、IOS、Web Android、IOS

上面Apk大小是通过 react-native initweex create 和 flutter
创建出的工程后,直接不添加任何代码,打包出来的 release 签名 apk
大小。从下图可以看出,其中大比例都是在so库。

图片 6

react native 作为 Facebook
主力开源项目之一,至今已有各类丰富的第三方库,甚至如 realmlottie
等开源项目也有 react native
相关的版本,社群实际无需质疑。当然,因为并完全正统开发平台,第三库的健壮性和兼容性有时候总是良莠不齐。

weex 其实有种生错在国内的感觉。其实 weex
的设计和理念都很优秀,性能也不错,但是对比 react native
的第三方支持,就显得有点后妈养的。2016年开源至今,社区和各类文档都显得有点疲弱,作为跨平台开发人员,大多时候肯定不会希望,需要频繁的自己增加原生功能支持,因为这样的工作一多,反而会与跨平台开发的理念背道而驰,带来开发成本被维护难度增加。

Flutter目前还处理beta阶段,但是谷歌的号召力一直很可观,这一点无需质疑。

理论上 flutter
的性能应该是最好的,但是目前实际体验中,却并没有感受出来太大的差距,和
react native、weex
在性能上个人体验差异不是很大。当然,这里并没有实测渲染的毫秒时间和帧率数据。

  • Weex的多页面实现问题

weex 在 native 端是不支持 <keep-alive> 的,这一点和 react-native
不同在与,如果在 native 需要实现页面跳转,使用 vue-router
将会惨不忍睹:返回后页面不做特别处理时,是会空白一片。参考官方Demo
playground,native 端 的采用 weex.requireModule('navigator') 跳转
Activity 是才正确实现。

同时,weex中 navigator
跳转的设计,也导致了多页面的页面间通讯的差异。weex在多页面下的数据通讯,是通过url实现的,比如file://assets/dist/SecondPage.js?params=0,而vuex和vue-router在跨页面是无法共用的;而
react native 在跨 Actvity 使用时,因为是同一个bundle文件,只要 manager
相同,那么 router 和 store 时可以照样使用的,数据通信方式也和当个
Actvity 没区别。

  • 项目模板

weex 和 react native 模板代码模式也不同。weex 的模板是从 cordova
模式修改过来的,根据platform需求,用命令添加固定模块,而在 .gitignore
platforms 文件夹是忽略跟踪。 react native
在项目创建时模版就存在了,特别是添加第三方插件原生端支持时,会直接修改模板代码,git代码中也会添加跟踪修改。

我们选择框架的时候,很多时候会关注框架的成熟度和生命力不是么。

总结:

这些知识我自己的一些思考与理解,如果你有自己的想法还有理解,欢迎留言一起讨论

我的简书

源码分析

首先来分析下React以及Preact在setState部分的具体实现。

(太长不看想偷懒,可以直接下翻看结论)

跨平台一直是老生常谈的话题,cordova、ionic、react-native、weex、kotlin-native、flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头。(事实上更多是共存发展)看完本篇,相信你会对于当下跨平台移动开发的现状、实现原理、框架的选择等有更深入的理解

3.2劣势:

  • 扩展性仍然远远不如web,也远远不如直接写Native
    code(这个不用废话解释了吧)
  • 从Native到Web,要做很多概念转换,势必造成双方都要妥协。最终web要用一套CSS的阉割版,Native要费劲地把这个阉割版转换成native原生的表达方式
  • RN框架原生并不支持Web端。这意味着如果一个业务需要同时上Android、iOS和H5页面的话,那除了用RN之外,还需要用传统的H5或用ReactJS框架再做一次开发,这样效率是非常低的。
  • Facebook给出的官方RN
    API不能完全满足业务快速的发展。它只给了一些很基础的API,但业务中经常会用到的一些多媒体,比如录音、录像、视频播放文件以及文件上传、压缩、加密等等,这些都没有提供。也就是说我们需要这些功能,还是需要原生的同学配合一起扩展的

群昵称:杭州-批判(43****117)
  1. ES6你必须掌握的新特性
…很多关于前端的文章

划重点

相同点:

  • 在 componentWillReceiveProps 中 setState 都会应用到 nextState。
  • 在 shouldComponentUpdate 中 setState 都会应用到
    nextState,但是可以直接操作传入的 nextState。

不同点:

  • React下 setState 的值不会立即生效,会一直积累到
    componentWillReceiveProps,在此之后会进行合并,并提供给后续生命周期。而Preact下
    setState 会立即反映到 this.state,但是,在更新组件的生命周期到
    render 前(eg: shouldComponentUpdate), this.state 将会是 prevState。
  • shouldComponentUpdate 阶段 setState 虽然不会影响到最终 state
    的值,但是Preact下会影响 this.state 的值,比如之后
    componentWillUpdate 中的 this.state, 总之此阶段不要 setState
    反正也没用。
  • setState 如果使用函数修改,Preact下传入的 props 将会是
    prevProps,而React中是 nextProps,在 componentWillReceiveProps 中
    setState 时要注意。
  • react nativeweex均使用JavaScript作为编程语言,目前JavaScript在跨平台开发中,可谓占据半壁江山,大有“一统天下”的趋势。

  • kotlin-native开始支持 iOS 和 Web
    开发,(kotlin已经成为android的一级语言)也想尝试“一统天下”。

  • flutter是Google跨平台移动UI框架,Dart作为谷歌的亲儿子,毫无疑问Dart成为flutter的编程语言,如下图,作为巨头新生儿,在flutter官网也可以看出,flutter同样“心怀天下”。

源码地址

上面的只是一个案例,如果后续想要真正的实现三端统一的功能,
还是需要自己去实现一套转换方案,这样组件就可以进行扩展.
实现思路可以借鉴淘宝的react-web

这边还有一个比较好的转换实现方案:
react-native-web
作者目前也在持续更新,目前关注已经有5000+


欢迎加入我的QQ群:397885169,一起学习react-native,一起成长。

setState 阶段:

// ReactUpdateQueue.js
enqueueSetState: function(publicInstance, partialState) {
  ...

  var queue =
    internalInstance._pendingStateQueue ||
    (internalInstance._pendingStateQueue = []);
  queue.push(partialState);

  enqueueUpdate(internalInstance);
}

可以看到React在 setState
的时候不会做任何处理,会把变更直接放到一个专门处理 state
的队列里供组件更新时使用。

3、Flutter

Flutter 是 Google 跨平台移动UI框架,Dart作为谷歌的亲儿子在 Flutter
中使用,并且谷歌新操作系统 Fuchsia 支持 Dart,使用 Flutter
作为操作UI框架。这些集合到一起难免让你怀疑 Android
是否要被谷歌抛弃的想法。

或者如今先 Android 等平台上推广 Flutter 与
Dart,就是为了以后跟好的过渡到新系统上,毕竟开发者是操作系统的生命源泉之一。而
Java 与 JVM 或者可以被谷歌完全抛开。当然,目前看起来 Flutter
貌似还缺少一些语法糖,嵌套下来的代码有点不忍直视,或者到正式版之后,我们更能感受出它的美丽吧。

内容有点长,其实很多点并没有细致的展开说明,但是通过本文,对于移动端跨平台的现状与未来,希望可能给你带来一点帮助。

类型 链接
react-native https://github.com/CarGuo/GSYGithubApp
weex https://github.com/CarGuo/GSYGithubAppWeex
Flutter https://github.com/CarGuo/GSYGithubAppFlutter
  • 从Android到React Native开发

  • 从Android到React Native开发(二、通信与模块实现)

  • 从Android到React Native开发(三、自定义原生控件支持)

  • 从Android到React Native开发(四、打包流程和发布为Maven库)

  • Weex原理之带你去蹲坑

图片 7撸文真的好累

4 React native 常用组件和api

基础组件

图片 8


用户交互组件

图片 9


列表组件

图片 10


ios特定组件和api

图片 11


android特定组件和api

图片 12


其他功能组件和api

图片 13

图片 14


上面都是一些ReactNative官方提供的组件和API,
虽然官方有说一套代码代码实现andriod和ios平台的通用,
不过我们有时候还是需要在特定的场景做一些平台判断,
显示对应平台的代码,

如:

if(Platform.OS === 'android') {
   //安卓平台组件
}else if(Platform.OS === 'ios') {
  //ios平台组件
}

提供一些目前开源的扩展组件:

  • react-native 组件库
    https://js.coach/react-native/redux-saga-process

  • 最佳轮播类组件
    https://github.com/leecade/react-native-swiper

  • A Native Picker with high performance.
    https://github.com/beefe/react-native-picker

  • 下拉刷新组件
    https://github.com/jsdf/react-native-refreshable-listview

  • 模态框
    https://github.com/brentvatne/react-native-modal

  • react-native-navbar
    https://github.com/react-native-fellowship/react-native-navbar

  • 滚动轮播组件
    https://github.com/appintheair/react-native-looped-carousel

  • HTML显示组件
    https://github.com/jsdf/react-native-htmlview

  • Material React Native (MRN) – Material Design组件库
    https://github.com/binggg/mrn

  • react-native-gitfeed – GitHub客户端(iOS/Android)
    https://github.com/xiekw2010/react-native-gitfeed

  • React-Native-Elements – React Native样式组件库
    https://github.com/react-native-community/React-Native-Elements

  • Shoutem UI – React Native样式组件库
    https://github.com/shoutem/ui


群昵称:郑州_大圣(89****856)

1.一款由React
Native编写的开源App–Gank
2.React Native
调用原生Android/iOS代码实现拨号功能

setState 阶段:

// component.js
setState(state, callback) {
  let s = this.state;
  if (!this.prevState) this.prevState = extend({}, s);
  extend(s, typeof state==='function' ? state(s, this.props) : state);
  if (callback) (this._renderCallbacks = (this._renderCallbacks || [])).push(callback);
  enqueueRender(this);
}

实现的简单粗暴,在 setState 的时候就进行了合并,会立即改写
this.state,在第一次 setState 时会保留 state 状态到
prevState。由于是立即合并state,如果入参state是函数,props 将只是当前
this.props。

2、WEEX

Alibaba 出品,JavaScript语言,JS V8引擎,Vue设计模式,原生渲染

“Write once, run everywhere”, weex的定义就像是:写个 vue
前端,顺便帮你编译成性能还不错的 apk 和
ipa
(当然,现实有时很骨感)。基于 Vue 设计模式,支持 web、android、ios
三端,原生端同样通过中间层转化,将控件和操作转化为原生逻辑来提高用户体验。

在 weex 中,主要包括三大部分:JS
Bridge
RenderDom,分别对应WXBridgeManagerWXRenderManagerWXDomManager,三部分通过WXSDKManager统一管理。其中
JS BridgeDom 都运行在独立的 HandlerThread 中,而 Render
运行在 UI 线程。

JS Bridge 主要用来和 JS 端实现进行双向通信,比如把 JS 端的 dom
结构传递给 Dom 线程。Dom 主要是用于负责 dom
的解析、映射、添加等等的操作,最后通知UI线程更新。而 Render
负责在UI线程中对 dom 实现渲染。

图片 15图片来自网络

和 react native一样,weex 所有的标签也不是真实控件,JS 代码中所生成存的
dom,最后都是由 Native 端解析,再得到对应的Native控件渲染,如 Android 中
<text> 标签对应 WXTextView 控件。

weex 中文件默认为 .vue ,而 vue 文件是被无法直接运行的,所以 vue
会被编译成 .js 格式的文件,Weex
SDK会负责加载渲染这个js文件。Weex可以做到跨三端的原理在于:在开发过程中,代码模式、编译过程、模板组件、数据绑定、生命周期等上层语法是一致的。不同的是在
JS Framework 层的最后,web 平台和 Native 平台,对 Virtual DOM
执行的解析方法是有区别的。

图片 16

实际上,在 Native 中对 bundle 文件的加载大致经历以下阶段:

  • weex 接收到 js 文件以后,JS Framework 根据文件为 Vue
    模式,会调用weex-vue-framework 中提供的
    createInstance方法创建实例。(也可能是Rax模式)

  • createInstance 中会执行 Js Entry 代码里 new Vue()
    创建一个组件,通过其 render 函数创建出 Virtual DOM 节点。

  • 由JS V8 引擎上解析 Virtual DOM ,得到 Json 数据发送至 Dom
    线,这里输出 Json 也是方便跨端的数据传输。

  • Dom 线程解析 Json 数据,得到对应的
    WxDomObject,然后创建对应的WxComponent 提交 Render 。

  • Render在原生端最终处理处理渲染任务,并回调里JS方法。

得益于上层的统一性,只是通过 weex-vue-framework 判断是由Vue.js
生成真实的 Dom ,还是通过 Native Api 渲染组件,weex 一定程度上上,用JS
实现了 vue 一统天下的效果。

图片 17图片来源网络

weex 在原生渲染 Render
时,在接收到渲染指令后,会逐步将数据渲染成原生组件。Render
通过解析渲染数据的描述,然后分发给不同的模块。

比如 控件渲染属于 dom
模块中,页面跳转属于navigator模块等。模块的渲染过程并非一个执行完,再执行另一个的流程,而是类似流式的过程。如上一个
<text> 的组件还没渲染好,下一个 <div>
的渲染又发了过来。这样当一个组件的嵌套组件很多时,或者可以看到这个大组件内的UI,一个一个渲染出来的过程。

weex 比起react native,主要是在JS V8的引擎上,多了 JS Framework
承当了重要的职责,使得上层具备统一性,可以支持跨三个平台。总的来说它主要负责是:管理Weex的生命周期解析JS
Bundle,转为Virtual
DOM,再通过所在平台不同的API方法,构建页面
进行双向的数据交互和响应

图片 18

weex 作为 react-native
之后出现的跨平台实现方案,自然可以站在前人的肩膀上优化问题,比如:Bundle文件过大问题

Bundle文件的大小,很大程度上影响了框架的性能,而 weex 选择将
JS Framework 集成到 WeexSDK 中,一定程度减少了JS Bundle的体积,使得
bundle 里面只保留业务代码。

打包时,weex 是通过 webpack 打包出 bundle 文件的。bundle 文件的打包和
entry.js 文件的配置数量有关,默认情况下之后一个 entry
文件,自然也就只有一个bundle文件。

在 weex 项目的 webpack.common.conf.js 中可以看到,其实打包也是区分了
webConfigweexConfig 的不同打包方式。如下图,其中weexEntry 就是
weex 打包配置的地方,可以看到本来已经有 indexentry.js
存在了。如果有需要,可配置上你需要的打包页面,具体这里就不详细展开了。有兴趣可看:Weex原理之带你去蹲坑

图片 19

5.三端同一套代码实现的思考

facebook官方的说法是react-native是为多平台提供共同的开发方式,而不是说一份代码,多处使用

但是在正常的项目中,我们还是希望一套代码能够在ios,android,web端都可以通用的,这样可以保留我们h5的优势,大大提升开发效率

业界目前已经有一些比较成熟的案例的,
比如
1.蚂蚁金服
蚂蚁金服有一套开源的react组件,支持web还有rn端,这是一个可以参考的三端统一方案
2.京东
京东这边也实现了一套三端统一的技术方案,不过目前没有可以参考的代码

图片 20


这篇文章也提过
其实在业内三端融合也有广泛的研究,方案主要有三种。

  • 第一种方式,就是在RN跟ReactJS之上再封装一套轻量的跨平台的抽象层,像微软发布的ReactXP就类似于这样的架构。使用这种架构,意味着所有API、类、组件都不能用RN
    API,必须要用新的定义的接口,而且目前API支持也不是太多,还在完善中,所以没有采用这种方式。

  • 第二种就是ReactJS做开发,之后通过工具转换成RN,这种方案适合于比较偏重H5业务的一些团队,因为他优先需要上的是H5页面,用户体验比较偏重H5。通过工具向RN转换其实是个有损转换,因为RN支持的样式实际比CSS样式少。从ReactJS向RN转换的话,可能会丢掉一些属性和布局。

  • 第三种方案就是先用RN做开发,开发完之后再通过WebPack工具向ReactJS进行转换。这种方式的好处是可以优先保证RN中的体验,而且RN的样式支持是CSS的一个子集,这意味着从RN向ReactJS转换不会丢失功能和属性,所以业内更多的方案也是采用这种方式。GitHub上有一些类似的开源框架。但它们支持的组件并不是太全,不能完全覆盖我们的业务,所以我们自己实现了一套。包括之前说的所有的原生组件,它只有原生部分,我们也增加了JS部分的实现,使我们的框架可以完整、功能完全没有丢失地转化为Web页面。


目前我这边就第三种方案自己做了一个案例,中间运用到到淘宝团队做的一个开源库
react-web

实现效果如下:

  • web端效果图

图片 21

  • android效果图

图片 22

  • ios效果图

图片 23


附上一些实现代码:

图片 24

web文件夹里面就一个页面,还有webpack配置文件去打包


ios入口文件

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Platform
} from 'react-native';

export default class reactnative extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('reactnative', () => reactnative);
if(Platform.OS == 'web'){
  var app = document.createElement('div');
  document.body.appendChild(app);
  AppRegistry.runApplication('reactnative', {
    rootTag: app
  })
}

重点在这一段:

if(Platform.OS == 'web'){
  var app = document.createElement('div');
  document.body.appendChild(app);
  AppRegistry.runApplication('reactnative', {
    rootTag: app
  })
}

实现思路就是在平台为web的时候,如果引入Text组件,webpack将会
生成一个Text.web.js组件,web端的时候将会引用Text.web.js 去实现
Text组件的效果,同时会把css子集编译为web元素的行内样式.

giants_one

总结

如果你写的工程需要同时兼容React及Preact的话:

  • 不要利用React下 setState 在同一次组件更新执行前 state
    不立即更新的特性,注意多个 setState
    之间是否影响,必要时手动保存旧值。
  • 在组件更新生命周期内,除 componentWillReceiveProps 之外不要使用
    setState,提供了 nextState 的生命周期,可以直接修改 nextState。
  • 尽量避免使用 setState 函数修改方式,在 componentWillReceiveProps
    中使用时,使用生命周期中的 prevProps(this.props) 和 nextProps。

p.s: antd-mobile
2.0正式版已发布,同时兼容react、preact,轻量、快速、易用的移动端组件库,等你来用~
【传送门】

类型 链接
react-native https://github.com/CarGuo/GSYGithubApp
weex https://github.com/CarGuo/GSYGithubAppWeex
Flutter https://github.com/CarGuo/GSYGithubAppFlutter

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注