面向未来的前端类库开发—KISSY类库构想与实践王保平(玉伯)@淘宝2010/12/18Topics•KISSY类库介绍•种子seed•种子的长大core•基亍mixin的UI组件构建•展望不重复造“相同的”轮子KISSYonGithub小巧灵活,简洁实用使用起来让人感觉愉悦componentscoreseed•switchable•calendar•overlay•…•dom•event•ajax•...•kernel•web•loader种子seedkernel{kissy.js,lang.js}loaderweb.jscore{dom/event/anim/ajax/…}componentswebappsseedkissy.js(function(host,S){varmeta={mix:function},seed=(host&&host[S])||{};host[S]=meta.mix(seed,meta,false);})(this,„KISSY‟);•原子(meta):varmeta={mix:fn}•宿主(host):(function(host,S){})(this,„KISSY‟);•种子(seed):seed=(host&&host[S])||{};meta.mix(seed,meta,false);•种子具有mix()和host两方面特性。•一个系统诞生自一个种子,host是种子的培育土壤,种子通过不断mix()而成长,可生长成任意复杂的系统。•传入的种子可以是已存在的复杂系统。用jQuery做种子scriptsrc=“jquery.js”/scriptscriptwindow[„KISSY‟]=jQuery;/scriptscriptsrc=“kissy.js”/scriptscriptKISSY(„pHelloworld!/p‟).appendTo(document.body);/script种子的长大scriptsrc=“labjs.js”/scriptscriptKISSY.mix(KISSY,$LAB);/scriptscriptKISSY.script(„a.js‟).wait().script(„b.js‟);/script基亍seed,构建基础类库的方式①seed+mix(开源类库)②seed+mix(自主研发)③seed+mix(开源类库+自主研发)•KISSY选择第三种方式•mix的开源类库有:sizzle,json2•seed和其他功能自主研发kernel的特性•host无关,可运行在任意宿主环境中例子一:在BESENShell中运行例子二:在PhotoshopCS5中运行好处一:在服务器端运行好处二:可装载到任意闭包,沙箱隔离•与ES5兼容面向未来,春暖花开kernel{kissy.js,lang.js}loaderweb.js与浏览器相关的方法模块注册/加载/调用loaderKISSY.add(„modName‟,{fullpath:„path/to/mod.js‟,requires:[„core‟]});KISSY.use(„modName,calendar‟,callback);•内置模块,无需add,直接use•支持静态和劢态两种方式用S.app构建应用KISSY.app(„D2‟);D2.add(„克军‟,{fullpath:„中国/北京/豆瓣‟});D2.use(„克军‟,function(){…});D2.namespace(„China‟);前端页面构建KISSYAppsPageLogicModuleModuleModuleModuleModule小结•系统诞生亍种子•种子通过mix长大•KISSY选择seed+mix(开源+自主研发)•seed里包含kernel+web.js+loader•kernel与host无关•构建应用的方式:S.app•kissyseed是一个独立的迷你类库种子的长大core模块化、颗粒化•模块是kissy里文件级的代码组织方式•一个模块可以由多个子模块组成API的20/80原则•实现常用的20%功能•满足用户80%的需求•例子一:selector默认只支持#idtag.class•例子二:dom中无range相关方法core层的实现方式attr的演化(1)DOM.getAttribute=function(el,name){}DOM.setAttribute=function(el,name,value){}attr的演化(2)DOM.attr=function(el,name,value){if(value===undefined){returngetAttribute(el,name);}setAttribute(el,name,value);}attr的演化(3)DOM.META.getAttribute=fnDOM.META.setAttribute=fnDOM.attr=publish(„Attribute‟);attr的演化(4)DOM.META={getAttribute:fn,setAttribute:fn,getStyle:fn,setStyle:fn,…};S.publish(DOM.META).to(DOM,config);attr的演化(5)S.publish(DOM.META).to(DOM,cfg);S.publish(Event.META).to(Event,cfg);S.publish([DOM,Event]).to(Node,cfg);S.Node(„p‟).attr(„data‟,„HedgerisanJSninja!‟);实现方式小结•一处只干一件事•用META层封装原子方法•用publish机制变换为publicapi•注1:目前尚未完成重构。•注2:要特别感谢QWrap团队的分享,publish构想借鉴了QWrap的retouch思路。•注3:做好后,会尝试将META层独立开源出来,使得能像sizzle一样,可复用到其他类库,可自由替换。基亍Base的组件开发Base示例小结•代码组织方式:模块化、颗粒化•代码实现方式:META层+publish变换•组件基础构建:Base基于mixin的UI组件构建基亍约定的UIBaseExtensionfunctionPosition(){}Position.ATTRS={x:{},y:{},xy:{}}Position.prototype={__renderUI:fn,__bindUI:fn,__syncUI:fn,_uiSetX:fn,__destructor:fn}•constructor/destructor•UI的三个阶段:renderUI/bindUI/syncUI•uiSetAttribute模拟C++的多继承基亍mixin的多继承小结•世界很复杂,完美的类抽象很难•适度继承+选择性mix•约定优亍配置•好处:可复用性高,整体维护方便•不足:成员冲突,门槛稍高展望Roadmap基础核心常用组件社区化、子品牌期待这里出现你的名字It’sNOTthedestination,butjustwhereweBEGIN!AnyQuestions?kissy::@lifesingerblog::lifesinger@gmail.com