python 客户端同构_react服务端/客户端,同构代码心得

FKP-REST是一套全栈javascript框架

react服务端/客户端,同构代码心得

作者:webkixi

react服务端/客户端,同构代码心得

服务端,客户端同构一套代码,大前端的梦想,为了省略重复的代码,却平添了不少烦恼,头发也白了,。。。。,妹子还在家等我.

目录结构问题

我们引用了很多的库,在开发前端代码的时候,习惯性的我们不会考虑到node端对于库的引用,这就是开始同构最大的痛点。整个目录结构需要调整。

减少调用层级

比如说开发前端时,有一个libs的库,在react的前端组件开发时,我们多次调用到libs里面的若干方法,这个时候,为了同构,需要将libs库做一个抽离,既是从前端代码中抽离到中间的部分。

这么说有点不好理解,简单配一个图吧。

FKP原来的结构

node -> fed -> libs -> component -> pages

大致上我们原来的结构都类似于这样,调整好之后的结构,如下:

node libs fed -> component -> pages

这样,我们将libs抽离到中间的部分,相对来说,在同构时,require的层级少了很多。但是还不够,为了 将react同构,我们还需要调整component的结构,如下:

node libs component fed -> pages

如此这般,大致的结构算调整好了,接下来解决require的坑,让webpack和node端require做到无缝切换。 让require('libs/index'),这种引用兼容于两端。 在这里FKPJS用到了一个好用的包文件app-module-path,指定node端require的目录优先级,及自写了一个 include的方法(封装require),来简化require的调用深度。 并对libs库做更细化的抽象与提取,最后,FKPJS的libs结构做到如上所述。

组件结构问题

解决了目录结构问题后,为了做到同构,我们需要合理的组件结构,以方便两端的调用,经过本人的实践,FKPJS将组件分为三层,原子组件,组合组件,组件封装,如下图

原子 -> 组合 -> 封装

1. 原子组件(react/widgets)

适用node/fed,复用型组件,最小粒度化,产出纯结构,纯粹的react组件,封装了对数据的处理

2. 组合组件(react/modules/xxx/_component/xxx)

适用node/fed,组合不同的原子组件,并引入相关mixins,实现like redux,产出纯结构,纯react组件,传输数据

3. 组件封装(react/modules/xxx/yyy)

适用于前端,最表层,处理配置文件,可导入JQ等库实现内部逻辑、效果,并响应由业务层传导进来的方法,数据等等。

在FKPJS中封装的比较好的有两个组件,react/modules/pagination/pagi,react/modules/list/base_list.jsx,list组件有点复杂,我们先说下 pagi这个组件吧

pagi这个组件,用于分页,可前后端同构

前端业务中实现的代码

varPagi=require('modules/pagination/pagi'),// 初始化分页数据pageData={total:60,per:20,url:'/',query:'page='}Pagi(pageData,{container:'pagi',begin:{start:0,off:5},itemMethod:bindItem})

服务端同构的代码

// pages/pagi.jsvar_props={itemMethod:false,listMethod:false,itemClass:'',listClass:'pagenation wid-12',data:{total:60,per:20,url:'/',query:'page='},begin:{start:0,off:5}}varreactHtml=yieldreact2html('react/modules/pagination/pagi',_props)reactHtml[0]='

'+reactHtml[0]+'
'oridata.pagi=reactHtml[0]return.....

组件封装

封装部分

// 封装方法functionpagination(data,opts){// 处理配置文件varnoop=false,dft={container:'',globalName:'_Pagi',itemMethod:noop,listMethod:noop,itemClass:'',listClass:'pagenation wid-12',data:{total:200,per:10,url:'/',query:'page='},begin:{start:0,off:7}}dft=_.assign(dft,opts)if(!dft.container)returnfalse;if(data){dft.data=data}// fkp redux// 初始化组件数据// FKPJS使用SA代替redux// 需要在组合组件中引入,store的minxinSA.set(dft.globalName,{data:data,begin:dft.begin})// fkp redux// 将组建的action放到 SA 的全局名字中// 需要在 _Pagi组件中引入 store 这个mixinsvarPagi=_Pagi(dft.globalName)// 渲染组件render(,document.getElementById(dft.container))}// 服务端同构,执行这个部分pagination.server=function(){return_Pagi(true)};module.exports=pagination

组合组件

这里不贴出所有代码,部分

varList=require('../../../widgets/listView/list');varStore=require('../../../mixins/store');//引入这个就完成了reduxvar_storeName;var_jump=false;// List的item组件varPageItem=React.createClass({componentDidMount:function(){varele=React.findDOMNode(this),mtd=this.props.itemMethod,dmtd=this.props.itemDefaultMethod;if(dmtd&&typeofdmtd==='function'){dmtd.call(ele,_storeName,mtd);}},.......

组合组件-算法部分

render:function(){if(this.state.data){vardata=this.state.data,newData=[],pages=data.total/data.per,pre,aft,half,begin=this.state.begin,........

组合组件-实现部分

functionactRct(storeName){// 根据storeName,可以实现多个组件,并redux化// for serverif(storeName===true){returnReact.createClass(pagenation);}// for client_storeName=storeName||'_Pagi';var_rct=_.cloneDeep(pagenation);if(_rct.mixins&&_rct.mixins.length){_rct.mixins.push(Store(_storeName))//实现redux}else{_rct.mixins=[Store(_storeName)]}returnReact.createClass(_rct);//返回react组件

原子组件

综上所述,做到两端同构的话,需要有一个全局的眼光,从基础的目录结构开始,到组件的结构,其实还有css的结构,html的结构,这里就不一一说明了,希望能抛砖引玉

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值