摘要:重构前的技术文档调研与分析,包括技术选型为何选择react,应用过程当中的注意事项等。css
React是当前前端应用最普遍的框架。三大SPA框架 Angular、React、Vue比较。html
目前来看React的生态系统要比Vue大的多,在github、stackoverflow等最大的技术社区搜索二者,React的搜索结果是Vue的十倍左右,另外据近期统计使用React的站点是Vue的几百倍以上。更大的生态意味着更多可用的资源,以及遇到问题能够获得更多的有效参考与帮助,这也是除了性能以外选择React的核心缘由。前端
选择React以后,应用会在如下几个方面有提高。java
三大框架在移动端分别有本身的东西。Angular的ionic,React的React Native,Vue的Weex。其中ionic 是基于cordova技术,依然是浏览器应用。然后二者已上升到操做原生控件的层面,作出来的是原生界面,其中React Native的成熟度远高于Weex,已经被不少公司使用,而Weex使用者不多。node
综合来看选择React 生态明显最佳,由当前的cordova过渡为cordova+Reactjs,而后能够平滑地过渡到React Native,媲美原生性能的最优混合开发方式。之因此说平滑是由于React Native中近90%的代码(JS)能够在IOS和Android端使用,剩余的涉及原生的代码也基本能够找到可用的资源,就像cordova 的插件同样。毕竟若是须要同时掌握JS, OC(或swift),java(或kotlin)才能开发React Native的话,那这门技术不会有人用;固然反过来若是有原生开发知识的话会对开发React Native有必定帮助。react
直接转型为React native的话涉及了应用底层架构的变更,有比较大的跨度,而转为cordova+Reactjs相对容易,而由cordova+Reactjs到React Native一样容易很多,由于其中大部分Reactjs代码能够重用。webpack
首先开发脚手架官方出了Create-react-app,集成了webpack-当前最流行的打包工具,babel-提升js版本兼容性的转码器,以及ESLint-代码检测工具和其它一些经常使用工具,同时对这些工具进行了比较优的配置。值得一提的是该脚手架将这些工具的配置文件进行了隐藏,本意是让使用者专一于编码便可,但实际使用时一般会有本身配置的需求,此时执行npm run eject便可出现被隐藏配置文件。css3
React-router 是官方推荐的路由管理工具,因为是单页应用区别于原先的html界面间跳转,跳转实质是在组件间进行,因此须要有路由管理工具来统一化管理。这里值得一提的是,React-router配合webpack能够实现代码的按需加载。git
通常来讲,webpack打包后会在生成一个压缩的js文件,在单页应用打开会总体加载这个文件,因为该js文件包含以前全部的js代码,虽然进行了压缩,通常仍至少有几百kb,当应用稍微复杂点,打包后文件会相应变大。而加载的时候,无论那些代码有没有执行到,都会下载下来并进行加载,形成性能浪费,这一点在显然在web端很重要,而在cordova中是将js代码直接打包在本地,等于跳过了下载步骤但仍然会有加载过程。经过在router中写require.ensure代码并在webpack中相应地修改配置便可将js分红多个文件,在须要时加载对应的js文件,实现按需加载。github
Redux 是应用最普遍的第三方状态管理工具,其做用是当应用中多数据状态交互时,能够更有方便且代码结构清晰地统一管理状态,下图给出了形象的阐释。因为在实际开发中通常是分人员/分功能模块独立开发,考虑引入redux的成本(redux自己略复杂),能够在没有多数据交互的模块不使用redux,而在相似涉及增删改查的表单以及即时通信websocket等契合redux的模块使用。
为项目选取合适UI组件库,必定程度上简化UI样式的开发而且考虑使用其提供的过渡动画效果。这方面有比较多的选择,Google Material Design 风格的Material-UI在github上最受欢迎,但其设计语言与咱们当前APP大相径庭,腾讯的weui和阿里的antd-mobile 较为相近,其中antd-mobile与create-react-app脚手架配合使用时配置项比较繁杂,由于阿里本意是用来配合本身的脚手架dva(封装了react-router和redux),所以暂时选择weui,后期开发有特定组件需求可结合其余ui库使用。
至于页面跳转时的过渡动画,有些UI库给出了一些过渡样式,好比touchstone。但该库已再也不维护,文档不佳,且与新版本的react-router配合使用有不兼容状况。后来浏览官方文档发现官方有动画库react-addons-css-transition-group,使用该库结合css3的动画三件套animation,transition,transform便可实现各类动画效果包括基本的过渡效果,好比渐进平移等。
另外关于css,由于是单页应用,因此若是不加处理,直接import css文件的话最终打包生成一个css文件会致使样式应用到全局,形成同类名样式相互污染影响。解决这个问题有不少种方案。Facebook积极探索css in js方式,但直接写内联样式代码可读性太差。目前解决方案中应用最普遍的是css-modules,即在webpack配置中开启module选项,使用styles对象来写样式。
解决的原理是将css类名在打包后编译成哈希字符串,保持其惟一性。但当想要使用全局样式时要再配置,稍显繁杂,且它类名编写的方式为对象的方式,须要总体修改,另外在使用它时,发现不支持-横线的类命名方式,支持下划线方式,推荐驼峰式,而咱们以前html中的样式类名大可能是横线命名,这意味着原html和css中的类名都要对应修改,考虑到样式类名很是多,这一方式舍弃。
另外有基于css-modules使用高阶组件的react-css-modules使用人数也比较多,容许横线命名方式且全局本地样式区分简单,但有benchmark测试代表其会较大程度拖累性能,因此也舍弃。解决这个问题要最大程度兼容原先css的写法,即改动最小,由于以前的css类样式数量庞大。
Webpack css-loader 有个属性 :local 加上以后类会变成局部做用域,即webpack会对该类型的类进行自动哈希转码处理,但显然类名一个个加:local 是有些呆板的工做,因而想到能够利用scss的嵌套属性将:local在一个css文件中统一加到类名前。这里涉及到在脚手架create-react-app 添加对scss的支持,在命令行执行安装,并在package.json的scripts中添加watch-css指令,将原css文件改成scss文件,而后在最外层添加:local,执行watch-css命令,便可在scss文件旁自动产生css文件,且类名前自动添加:local 前缀,这种方法实践中发现并不是全部类的样式都与:local 兼容良好,相应的可使用文件名代替:local,要作的就是保持文件名的惟一性,这一点原工程下的文件名已知足。这样原先文件中引入css的方式,全局css引入的方式都不须要变化,作到最小代价。
scss 是 sass 3 引入新的语法,其语法彻底兼容 css3,而且继承了 sass 的强大功能,sass和less是前端扩充css经常使用的方式,添加了嵌套,变量,继承等语法,但须要编译成css来最终使用(稳定性考虑)。
开发Reactjs使用官方提供的脚手架Create-react-app,最终经过npm run build生成一个单页网页应用,放入cordova的www目录下便可。因为这两部分开发时独立,而原先开发是在含www目录的cordova工程目录下直接开发,这种不一样会产生一些问题。好比cordova中某些插件安装后export函数或者变量供引入使用,由于一开始是分离的,在create-react-app中并找不到这些变量,就形成在build的时候产生变量undefined的错误,尽管最终放到cordova工程中后能够找到变量并正常运行,但在第一步react开发时控制台报一堆error会妨碍调试,影响开发体验。
在github上有一些react cordova 库,但实质上它们都须要经过npm run build来打包,因此并无解决引入插件变量的问题,且会与create-react-app 有相斥的地方。因此要想办法使插件提供的变量在React中不报错,这里在不影响ESLint 检错机制的状况下能够采起迂回的方式。Build时控制台报错仅针对src文件夹下的代码,而在public文件夹下还有个index.html这个文件会最终被打包放到www目录下,所以能够在这个文件中deviceready时添加全局的插件变量(注意该类全局变量的惟一性,能够添加plugin前缀或使用命名空间等方式保证),并将值传给src目录下的代码中,这样便可绕过控制台build以及调试时的报错。
另一个小技巧能够将react工程直接放在cordova工程目录下,指定最终build生成的文件放入www目录下,省掉手动转移文件的过程。
还有须要注意的一点是因为React中默认配置的公共路径是绝对路径,当放在cordova中时须要使用file协议放本地,须要在webpack的production配置的public路径前加".",或者在package.json 文件增长一行"homepage": "../www"或"homepage": "."改成相对路径,不然会出现找不到文件的状况,这里推荐最后一种方式。
首先IDE选取webstorm,功能强大,以前项目组在用能够沿用下来,但须要注意的一点是当目录中包含了安装的依赖node_modules时,因为该文件夹下文件数量很是多,webstorm在智能创建代码关联时会占用大量资源,在某些电脑上会偶尔会出现卡死现象,这一现象在我配置比较高(固态硬盘加8g运存)的电脑上一样出现了,解决办法是在file-setting-File types中配置ignore node_modules 文件夹。
上图是create-react-app 项目的目录,主要代码放在src目录下。Components中包含全部组件。React严格地执行组件技术,组件化不只方便重用,一样能够将一个页面清晰地分割为几个部分最后放入一个父组件展现,由于jsx技术将js和html放在了一块儿,分割后每一个部分有本身的功能逻辑与页面展现,这样更加清晰易维护。事实上react提出了一切皆组件的思想,只是有的组件render了部分界面,而有的没有render。
上图中components下有common文件用来放项目成员本身写的公用组件好比公共请求方法等,external放外部引入的组件,work_log里放的是我写的工做日志模块的组件,各个功能模块都各自建立一个文件夹,命名规则统一使用下划线方式,这也是以前使用的方式。具体功能模块的划分与层级关系能够参考以前的.
值得一提的,之前html的层级关系必须严格为两层(涉及到跳转路径的逻辑),致使最后出现没有把一个功能模块放到一个文件夹里的状况,好比上面的工做日志以前所包含的各个文件直接和其它的一些功能模块一块儿放到了setting文件夹内。而如今只要在React-router统一配置好路由,实质上是往某个组件跳转,不存在跳转路径的限制。
Constants文件夹下存放各类常量,好比各类接口路径。Fonts存放字体图标文件,images存放图片,redux文件夹下是redux的几个组成部分,styles下放scss/css样式文件。Index.js是入口也是最顶层的父组件,router.js则维护了整个应用的路由关系。
上面就是本次调研的技术分析文档,浏览大量技术文档,开源社区以及技术论坛并结合实践摸索得出的选型思路和理由,可能依然会有一些点没有添加进去,之后会结合新知识和实践继续完善。
做者:梁鑫
来源:宜信技术学院