createTime:2016-09-28 16:30:55
原文地址,欢迎star!
总结下项目的问题,收获,不足。javascript
产品功能:能够查看 http://www.baifendian.com/pro/subject-67.html
简单的讲,该系统提供一整套的大数据解决方案。 客户拥有大量的数据,而后如何从这大量数据中,清洗出有价值的数据。css
若是上图看不到,点击这里html
5个前端,10个后端,1个运维, 开发调试用时3个月, 测试用时1.5个月。前端
前端技术:React全家桶 + webpack + gulp + ES6 + babel + less (react0.14)
代码版本控制使用:SVN
后端技术:Java + 大数据相关 【略】java
大数据操做系统,由多个模块组成,每一个模块能够理解成一个Project, 能够单独运行,不依赖其余模块。 而后由web桌面集成在一块儿。node
- BFD-UI 公共组件库 - CommonComponent 公共样式,Ajax处理,正则,针对产品定制组件部分 - DataFactoryModel 项目应用的工做流框架 - ConfigCenter 项目 - DataFactory 项目 - FilaManage 项目 - SecurityCenter 项目 - node_modules
- common 项目间公共代码 - container 项目布局 - modules 一级模块目录 - ide 一级模块 - components 页面 - css 样式 - enum 枚举 - model Ajax相关操做 - util 工具 - index.js react-router 路由 ... - workflow 一级模块
项目中考虑的问题和遇到问题的解决思路react
相对刚开始,先后端还搞在一块儿,前端开发还须要搭建后端环境,而后后端改配置,前端竟然跑不起来了,要抱着电脑去请教后端,这个坑啊。模块化开发好很好,只须要关注本身的模块。webpack
先后端分离, 项目采用模块化,每一个人负责几个模块,模块内包含该模块的全部内容,除了公共的部分,保证直接删掉该代码,并去掉路由,直接能够去掉该模块,添加模块等同。
这样模块解耦,方便应对需求变更,权限控制。git
这一块还好,没有遇到啥大问题。程序员
组件须要分为:公共基础组件,公共定制组件,具体业务组件
公共基础组件:建议采用第三方组件库,本项目使用公司的组件库,公司组件库刚开始研发,过程当中各类BUG,版本迭代间,高版本用于与低版本用法不同,不少坑爹的问题。
公共定制组件:在公共基础组件的基础上,封装成各个项目中,能够快速使用的方式,方便项目间统一维护,快速方便使用。 好比(表格数据处理,翻页处理,全选逻辑。。。)
具体业务组件:具体页面模块,但具体页面中,也有共用的部分。 最多见的就是编辑页面和建立页面能够共用。
覆盖组件样式是一个坑,由于公司组件也在研发中,做为第一个吃螃蟹的团队,就。。。。
组件库的样式,刚开始使用模块化+嵌套的方式, 后面组件库丰富了,发现有一些命名重复啦,重复啦。而后大改版,使用BEM命名方式。若是只修改命名方式也就还好,最主要仍是修改了DOM结构,而后之间的覆盖样式都废了。
切记,切记,切记,使用稳定的组件库
组件库地址:https://github.com/baifendian/bfd-ui
已经提供第一个稳定版本,赞一个,一路过来不容易。
引用第三方的reset.css,好比(normalize.css),处理浏览器之间的小差别
公共基础组件已经有自带的样式,须要覆盖,换成UI设置的风格,覆盖公共组件的样式都放在一个文件中。好比 bfd-ui.less , 也能够放多个文件,而后放在同一个文件夹中。
总体布局的样式,单独抽离成 layout.less 文件
样式命名须要统一规范,不然容易形成样式名冲突。可使用 BEM的命名方式,虽然命名长了点,可是为了命名冲突,也值了。
less 的变量也能够单独抽取出来,放在一个 文件中。 方便后期统一修改。好比:global.less
//其余使用变量的地方引入 @import "global.less";
注意less 、 sass 的 import 和 css 自带的区别。
刚开始coding,Ajax尚未封装,你们写到业务逻辑里面,这样代码很乱,一个JS中,有页面,业务逻辑,混在一块儿。
还好及时提出了解决方案, 抽离Ajax这一层,先封装Ajax操做,而后每一个模块各自抽离出Ajax操做,模块中调用,就是一个方法的调用。
跨域: : 关闭浏览器安全策略
开发的时候,先后端是分离的,所以前端访问后端接口的时候是跨域的。考虑到最终上线的时候,是部署在一块儿。 所以,上线后是没有跨域问题的。 所以可使用关闭浏览器安全策略来解决跨域问题。
Ajax接口地址: 可配置
开发的时候,可能要链接后端人员机子的IP地址,访问接口,调试完成可能要访问开发环境地址,上线须要访问上线部署的地址。 常常须要变更。 所以 接口的 基本路径 作成 配置。而后直须要改动配置,就替换了整个项目接口的访问地址。
Session过时,错误处理? 提供默认处理,并扩展接口自定义
项目开发,必须给Ajax封装一层,写统一的错误处理,错误提示,Loading效果,超时提示,Session过时等通用操做。
Ajax请求到一半,跳转页面,须要在 componentWillUnmount 中断Ajax请求。不然会报 组件已经卸载,不能使用 this.setState操做的错误。
每一个程序员都有本身的代码风格,可是,可是,可是团队开发就须要共同遵照一个代码规范。
这一块React生命周期,你们都按照顺序写,还行。其余方面因为赶时间,基本是 一个 格式化功能搞定。
JS代码规范只能口头上说说,由于实际上会不会执行,还得要比较大的Review力度。所以可使用 eslint 来进行验证,在提交前要验证下。【验证的比较粗糙】
还有一些则须要团队之间遵照,好比使用React, 编写生命周期的时候,请按照顺序来。
constructor componentDidMount componentWillReceiveProps shouldComponentUpdate componentWillUnmount ... 其余自定义方法 ... render
建立React组件,统一使用 ES6。加 autobind 方法
模块功能复杂的状况下,最好先理清总体流程,操做事件,而后在coding。
写IDE模块的时候,刚开始认为这个很简单,而后直接啪啪啪开始coding了,后面发现都是坑,很是多的细节问题。各类事件,各类交互。致使后面Review作了很大改动,切记切记,理清需求,不要看起来简单。
小模块内部,使用 prop或者 context 传递方法进行通信, 模块之间使用 事件派发。
这一块,公共样式,和布局方面作还行,可是公共组件方面有很大的问题,有时候更新组件忘记通知你们,致使跑起来报错。还有必须注意的是,进入测试阶段就不要更新整个组件库了,有BUG本身打补丁修复。由于更新组件引入新的BUG,被测试一直说。
公共样式在整个项目中,各个页面都用到,所以修改公共样式须要慎重。尽可能不要使用一些奇淫技巧,写一些稳妥的。
后台类型的管理系统,须要有不少的表单,有不少表单就有不少表单验证。
能够抽离出正则表达式统一放在一个文件中,其余各个地方都使用该文件里面的正则,文件中没有,则添加上。
在项目中,除了抽离正则,还封装了有验证功能的表单组件,而后直接配置正则,和错误信息(也能够动态生成错误信息),便可使用。
这一块在该项目中,作的还不错。
测试阶段,尽量减小修改BUG而引起新的BUG。所以必须写清楚每次提交代码的做用。
研发阶段还好一点,作好一个就能够提交一个,而且稍微注明下 上传什么模块代码就好了。
测试阶段,修改BUG,就必须遵照SVN提交规范
这一块分为两种,按钮控制,模块控制
在项目刚加载的时候,同步请求,权限数据,而后判断 data-code是否有权限,没有的话, 则 不 render 到页面上
按钮的权限控制,在最初的预想是,渲染到DOM后,在remove DOM 节点,后面发现这个想法是不可行的。
React 的 componentDidMount 回调里面, 不能够remove DOM节点,不然报错。
最终封装了一个组件,替换页面上全部须要控制按钮 , 图标按钮,超连接,下拉框选项,右键菜单。
renderType 属性执行渲染成什么类型组件(按钮,下拉。。。)
data-code 核心: 按钮标识,和后端匹配上
<AuthButton style={{marginLeft: 2,marginRight:20}} data-code="1021002" renderType="icon" type="plus-square" onClick={this.addScript.bind(this)}>新增</AuthButton>
模块控制,则控制导航菜单便可。 过滤掉没有权限导航选项,而后把有权限的渲染出来。
每一个模块的代码,是按需加载的, 也就是刚进入项目页面的时候,没有加载 模块的JS代码,这样减小了进入系统的时间很长。
【关掉第二个选项卡,可接口是关闭第三个选项卡】
主要问题是:对 React 的 key 和 render原理 的相关知识支持了解不够。
tabs 的内容是 存放在 数组中,循环渲染出来的,新增一个 tab,会往数组中添加一个tab,
而后react就会 从新 render,渲染出 tabs 组件。
修改前使用 index 作为key
<TabList> {this.renderTool()} {this.state.tabs.map((tab,index) => { return ( <Tab key={index} activeKey={index}> {this.renderTabTitle(tab)} </Tab>) })} </TabList>
修改前使用一个惟一标识做为key,就搞定了。
<Tab key={tab.uuid} activeKey={tab.uuid}>
一句话就是:想要更新组件内容,请保证当前组件的key与上一状态组件的key不一样。
具体能够看《ReactJS 组件的key做用》
虽然没有使用redux进行state管理,可是总体开发过程当中,没有体会到状态难管理。