新聞中心
介紹

伴隨著淘寶的快速發(fā)展,誕生已三年多的 KISSY 也取得了巨大的成長。 目前應(yīng)用于阿里集團的多個業(yè)務(wù)團隊,特別是淘寶,天貓,一淘的絕大多數(shù)業(yè)務(wù)都采用了 KISSY, 滿足了從前臺的 web page 到后臺的 web app 再到移動端應(yīng)用(起步階段)的廣泛需求。
在阿里集團以外也有不少公司和個人使用 KISSY,交流旺旺群成員已將近千人, 在 github 源碼庫也時常有外部人員參與提交 issue,發(fā)起 pull request,另外在 oschina 等開源社區(qū)也受到了一定的關(guān)注。
淘寶在 2012 年 12 月 25 號發(fā)布了 KISSY ***版本 1.3, 在這篇文章中我將對 KISSY 1.3 結(jié)合在淘寶的實踐做一次全面概述,希望能對想了解淘寶前端技術(shù)的朋友有所幫助。
為什么選擇 KISSY
KISSY 作為國內(nèi)一個完全自底向上開發(fā)起來的框架,誕生三年來歷經(jīng)淘寶的各種業(yè)務(wù)變化的考驗,體現(xiàn)了 KISSY 的可擴展性,高穩(wěn)定性和可維護性。 它在以下方面具有一定優(yōu)勢:
·擁有大量的中文文檔: 方便不熟悉英文的國內(nèi)開發(fā)者快速入門學(xué)習(xí)。
·在國內(nèi)具備一定的社區(qū)規(guī)模: 通過旺旺群,google group,微博,官方網(wǎng)站等用戶隨時可以和開發(fā)人員快速交流。
·開發(fā)便捷: 在模塊化,組件以及工具輔助方面形成了一套完善的機制,可以高效應(yīng)對日常的需求開發(fā)。
·綜合借鑒國際框架類庫設(shè)計:
·在吸收 jquery 穩(wěn)定的 dom 核心之外提供了模塊化,按需加載的基礎(chǔ)架構(gòu)。
·在學(xué)習(xí) yui 堅實的架構(gòu)之外著重于組件開發(fā),積累了一批貼近淘寶應(yīng)用的組件集。
·在研究 extjs 優(yōu)秀的組件設(shè)計之外探索輕量級,可擴展的組件開發(fā),同時滿足 web app 與 web page 的需求。
·應(yīng)用場景廣泛: 在各種設(shè)備上都有所支持。
·可以使用 seed 和 core 簡單快速地搭建頁面
·也可以進一步使用 KISSY 的大量組件構(gòu)建富客戶端應(yīng)用
·也可以使用統(tǒng)一的 API 開發(fā)移動應(yīng)用
·更可以利用 KISSY 靈活的模塊化機制高效進行大規(guī)模團隊協(xié)作
不過由于 KISSY 開發(fā)時間還不長,在組件完備性以及可測試性上有待進一步完善,我們堅信這種情況會隨著團隊的不斷努力而逐步解決。
架構(gòu)
KISSY 的架構(gòu)由淘寶復(fù)雜多變的業(yè)務(wù)決定,在松耦合、無污染、模塊化的核心前提下,也從眾多優(yōu)秀類庫和框架的思路得到一些啟發(fā)。 如圖1所示:
圖1: KISSY 整體架構(gòu)圖
KISSY-architecture
·***層的 seed 是類似目前流行的 AMD 模塊化機制實現(xiàn),為了更高效地共享通用組件加入了自動 combo 的支持, 另外 seed 也包含一些像 each(循環(huán)數(shù)組以及對象),mix(合并對象),param(編碼對象為 url), ready(等待 dom ready)等常用的靜態(tài)工具方法以及 Path,Uri,Promise,UA 等模塊化需要用到的基礎(chǔ)類。
·seed 之上的第二層是處理 dom 兼容性的核心模塊,其中每個模塊都是由更小的模塊打包合并而來。 特殊之處在于 KISSY 把一些不標準瀏覽器的兼容代碼單獨抽取成內(nèi)部模塊,用戶可用的外部模塊會根據(jù)不同的設(shè)備分別依賴不同的內(nèi)部模塊。 雖然加載不同的具體實現(xiàn)模塊代碼,但是最終提供給用戶的是一致的模塊名,api 以及漸進增強的能力。 例如用戶使用 event 模塊,在 touch 設(shè)備上會加載 event/touch 模塊從而可以使用一些手勢事件, 而在 ie<9 下會加載 event/hashchange 模塊,以類似 es5-shim 的方式來補全瀏覽器的能力,提供給用戶統(tǒng)一的 api。
·第三層為組件架構(gòu)層。提供包括模擬 es5 屬性管理,插件和多繼承機制的 rich-base 模塊, 所有 UI 組件渲染機制的基類 component 模塊以及具備一定邏輯的模板引擎 xtemplate。
·第四層為獨立可用的 KISSY 組件,用戶可自由組合繼承搭建最終頁面。包括:
·工具模塊,例如拖放,調(diào)整大小,操作 swf,操作樣式表,mvc(model,router)架構(gòu)等。
·UI 組件,例如彈窗,菜單,標簽,日歷等。
·最外層為 KISSY gallery,KISSY 社區(qū)開發(fā)的一些通用模塊會放入 gallery 中, 從而可以方便得在所有使用 KISSY 的團隊間共享模塊。 如果該模塊確實十分通用則會經(jīng)過重構(gòu)放入 KISSY 自身。
#p#
模塊化機制
介紹
由于淘寶業(yè)務(wù)的復(fù)雜,為了提高代碼的可維護性和重用性,KISSY 在早期就引入了簡單的模塊化機制,并且隨著前端技術(shù)的發(fā)展而不斷改進。 KISSY 1.3 的模塊化機制與目前的 AMD 規(guī)范比較類似,并根據(jù)淘寶自身業(yè)務(wù)特點加入了自動 combo 功能。
注:combo 舉例:請求 a.tbcdn.cn/??a.js,b.js 相當于把 a.tbcdn.cn/a.js 與 a.tbcdn.cn/b.js 的文件內(nèi)容合并后返回。
KISSY 之外的每個模塊必須屬于一個包,一個包內(nèi)可以有很多相關(guān)模塊,它們具備相同的加載基地址。 包的設(shè)計一方面通過約定優(yōu)先配置的原則可以減少同一個包內(nèi)多個模塊的請求路徑配置, 另一方面也方便了部署在不同地址的多個應(yīng)用間互相調(diào)用模塊。 所以開發(fā)應(yīng)用前請先配置包地址,例如:
- KISSY.config('packages', {
- myapp: {
- base:'./x'
- }
- });
之后在 x 目錄下建立 myapp 目錄,并在 myapp 目錄下新建模塊 a 對應(yīng)的代碼文件: a.js
- KISSY.add(function(S,JSON){
- return JSON.stringify({a:'ok'});
- },{
- requires:['json']
- });
以及依賴 a 的入口主模塊 main 的代碼文件: main.js
- KISSY.add(function(S,DOM,a){
- S.ready(function(){
- DOM.text(document.body,a);
- });
- },{
- requires:['dom','./a']
- });
應(yīng)用模塊可依賴 KISSY 自身模塊,例如以上的 dom json。
***新建 index.html 來調(diào)用應(yīng)用模塊:
- // ... 上述包配置
- KISSY.use('myapp/main',function(){
- alert('page loaded');
- });
工具支持
打開上述 index.html 會發(fā)現(xiàn)鏈接數(shù)不少,有從淘寶 cdn 的鏈接也有本地的鏈接。 因此 KISSY 提供了配套工具 KISSY Module Compiler 進行腳本打包以及抽取依賴后用 cdn combo 來解決這個問題, 對工具有興趣可查看參考資料中的鏈接地址,以下僅作簡單介紹:
腳本打包
如果應(yīng)用腳本非常多,可以用 module compiler 將入口模塊 main 以及其依賴的所有應(yīng)用模塊打包壓縮到 main-min.js 中, 同時 module compiler 會生成一份依賴描述文件:
- KISSY.config('modules',{
- 'myapp/main':{
- requires:['dom','json']
- }
- });
接著設(shè)置 KISSY 啟用 combo 模式,并載入上述的依賴描述文件:
- KISSY.config('combine',true);
***修改 index.html 引用 seed-min.js,打開網(wǎng)絡(luò)面板后會發(fā)現(xiàn)現(xiàn)在只產(chǎn)生兩個鏈接請求:
- http://a.tbcdn.cn/s/kissy/??dom/base,json/native.js
- http://localhost/myapp/main-min.js
注:在 ie<9 等非標準瀏覽器下***個鏈接地址會加上 dom/ie json/json2 等腳本地址
抽取依賴
如果應(yīng)用腳本不多,并且自身服務(wù)器也支持 combo 的話,那么可以采用更加靈活的抽取依賴后全部 combo 的解決方案。 這時 module compiler 會做兩件事情:
補全模塊名,例如 a.js 變?yōu)?/p>
- KISSY.add('myapp/a',function(S,JSON){
- return JSON.stringify({a:'ok'});
- },{
- requires:['json']
- });
將各個模塊的依賴收集為一個單獨的文件,例如
- KISSY.config('modules',{
- 'myapp/main':{
- requires:['dom,','./a']
- },
- 'myapp/a':{
- requires:['json']
- }
- });
接著設(shè)置 KISSY 啟用 combo 模式,并載入上述的依賴描述文件:
- KISSY.config('combine',true);
訪問 index.html,打開網(wǎng)絡(luò)面板會發(fā)現(xiàn)同樣只產(chǎn)生兩個鏈接請求:
- http://a.tbcdn.cn/s/kissy/??dom/base,json/native.js
- http://localhost/myapp/??a.js,main.js
KISSY-PIE
KISSY 還提供了一套基于約定的前端打包解決方案 KISSY-PIE,通過統(tǒng)一的約定,提升應(yīng)用的可維護性,將大家從重復(fù)的打包腳本的編寫中解放出來。
KISSY-PIE 包括了以下功能:
·JS(KISSY 的模塊編譯,HTML 模板到 KISSY 模塊編譯,代碼壓縮)
·CSS(基于 CSS-Combo 的合并,壓縮)
·Less
·Sass
并且在命令行之外還提供了 web 操作界面,如圖2所示:
圖2: KISSY-PIE 打包界面
#p#
組件機制
核心
KISSY 目前包括眾多即開即用的組件, 包括工具性質(zhì)的例如 dd(拖放),resizable(調(diào)整大?。?,swf(插入flash),stylesheet(操作樣式表)等 和 UI 性質(zhì)的例如 overlay(彈窗),menu(菜單),menubutton(菜單按鈕),imagezoom(放大鏡),editor(編輯器), tabs(標簽),tree(樹)等。 這些組件都基于公共的 rich-base 以及 component 模塊: rich-base 和 component 模塊充分利用了 javascript 語言的 mixin 和原型鏈繼承, 提供了屬性綁定,類繼承,擴展以及插件等特性。
其中的重點是 Component,它是所有 UI 組件的基類,提供了兩種通用的渲染方式:
·組件實例由 javascript 完全渲染 dom 樹。其中對于 menu 等組件在 javascript 完全渲染的情況亦可以通過 json 初始化內(nèi)部嵌套組件。例如
- KISSY.use('menu',function(S,Menu){
- // javascript 渲染一個菜單到 body
- new Menu({
- children:[{
- content:'item1'
- }]
- }).render();
- });
·從已有的 dom 樹節(jié)點得到組件實例。
下面以 KISSY 中常用的一個組件 Overlay 為例講解下,首先看圖3類結(jié)構(gòu)圖:
圖3: Overlay 類結(jié)構(gòu)圖
Overlay 繼承自 Component,然后靜態(tài)地由一些分散的功能類擴展而來,包括定位功能類,對齊功能類,關(guān)閉功能類,遮罩層功能類, 這些功能類底層利用 javascript 的 mixin 功能將自己的方法和屬性匯入到 Overlay 類中,使得最終的 Overlay 具備了這些能力。
組件在運行時也可以選擇性依賴某些插件模塊,將插件的功能注入到組件中去, 既避免了一個組件過于功能繁多導(dǎo)致的文件過大,又大大增強了組件的可擴展性。
以下為 Overlay 的使用示例代碼:
- KISSY.use('overlay,component/plugin/resize',function(S,Overlay,ReizePlugin){
- // 完全由 javascript 將組件實例渲染到 body 中
- new Overlay({
- content:'test'
- }).render();
- // 從已有的 dom 樹節(jié)點生成 Overlay 實例
- var overlay = new Overlay({
- srcNode:'#existing'
- }).render();
- // 運行時加入調(diào)整大小的插件能力
- overlay.plug(new ReizePlugin({
- handles:['t']
- }));
- });
Brix
除了 KISSY 自身的組件機制,一淘開發(fā)人員根據(jù)自己的應(yīng)用特點在組件開發(fā)和使用上找尋了另一條途徑。即 Brix 解決方案:
·基于統(tǒng)一的渲染方式:模板(tmpl)和數(shù)據(jù)(data)產(chǎn)生html片段后使用 innerHTML 到 DOM 節(jié)點中.
·提取子模板,結(jié)合數(shù)據(jù)的更新,達到局部刷新,開發(fā)者不需要再關(guān)心頁面的表現(xiàn),而專心于數(shù)據(jù)的變化。
·DOM 節(jié)點自定義屬性設(shè)置組件標志,Brix 提供 Pagelet 按照統(tǒng)一的方式實例化組件。
圖4: Brix 類庫結(jié)構(gòu)
設(shè)備普適性
當前 javascript 的使用范圍越來越廣,平臺包括 pc 瀏覽器與讀屏器,nodejs,移動端瀏覽器以及各種外殼,window8 等。 KISSY 也盡量在各個平臺給予支持,保證統(tǒng)一的開發(fā)體驗。
在 nodejs 上 KISSY 通過調(diào)整模塊加載器使得 KISSY 可以直接將自身的模塊加載到 nodejs 中使用。例如
·可以使用 KISSY 的 UA 解析模塊來分析日志中的 UA 串
·可以載入 jsdom 模塊在 nodejs 環(huán)境下做單元測試
·用 xtemplate 在服務(wù)器端渲染前端模板
·使用 KISSY 的 htmlparser,color 等工具模塊
經(jīng)統(tǒng)計約有 1000 萬殘疾人用戶在使用淘寶,其中不少是受影響***的盲人朋友,他們實際上是通過讀屏器來和淘寶交互, KISSY 組件通過遵循 WAI-ARAI 規(guī)范來給視力受損的朋友提供無障礙的訪問環(huán)境,網(wǎng)上人人平等。
KISSY 也計劃對 windows8 進行支持,在即將發(fā)布的 tmall windows8 app 中僅僅通過使用 KISSY 的模塊化機制以及一些語法糖 API 就可以達到和平常開發(fā)一樣的高效。
隨著用戶越來越多地在移動設(shè)備上購物產(chǎn)生交易,移動應(yīng)用在流量的比重上也越來越多,KISSY 及時適配移動設(shè)備, 目前在兩方面進行了支持:
·根據(jù)設(shè)備條件加載。對于移動端由于網(wǎng)絡(luò)速度等原因?qū)τ谖募笮”容^敏感,KISSY 為了保證一致的 API 又不能隨意刪減功能, 因而采取了獨立兼容模塊的方法來保持瘦身。在架構(gòu)一節(jié)也闡述過,KISSY 對基礎(chǔ)核心模塊中的兼容非標準瀏覽器的模塊進行選擇性加載, 同時移動設(shè)備上都是標準瀏覽器,從而可以大大減少實際下載到用戶設(shè)備上的代碼大小。部分組件也實行了拆分,將 pc 的功能交互獨立到單獨的模塊,在移動觸摸設(shè)備上只加載觸摸交互需要用到的模塊。
·漸進增強 API。對于觸屏設(shè)備,很多交互是建立在手勢操作上。而手勢操作除了在 safari 上有 gesture 事件做有限支持外, 在 android 上則完全沒有對應(yīng)事件。 得益于 KISSY 易于擴展的事件機制,KISSY 在底層多點觸摸 touch 事件的基礎(chǔ)上模擬出了 tap rotate pinch 等觸屏設(shè)備上獨有的事件,這對于用戶則是透明,用戶完全可以把這些事件當做原生事件來使用,例如
- KISSY.use('event',function(S,Event){
- // 監(jiān)聽 div 上的 tap 事件
- Event.on('#div','tap',function(){
- });
- });
ZOOJS
另外淘寶北京團隊還基于 KISSY 核心打造了專門面向 Web 無線設(shè)備的一整套工具庫 ZOOJS, 包含控件級的事件支持、觸屏行為的封裝、富控件、皮膚、App的基礎(chǔ)架構(gòu)等。 這套獨特的 Web 無線解決方案力爭將 HTML5 和 CSS3 的優(yōu)勢發(fā)揮至***,做到即調(diào)即用。
測試與持續(xù)集成
KISSY 經(jīng)過三年的開發(fā)代碼庫已經(jīng)相當龐大了,模塊間還常常有依賴關(guān)系,修改代碼有牽一發(fā)而動千鈞的后果。 為了應(yīng)對此問題,KISSY 也在逐漸完善單元測試,自動化測試與持續(xù)集成。
單元測試
KISSY 一個模塊的常見目錄結(jié)構(gòu)如圖5所示:
圖5: 模塊目錄結(jié)構(gòu)
其中 tests 目錄下為測試資源,runner 目錄下啟動測試的 html 文件,specs 下為對應(yīng)模塊的單元測試代碼。 KISSY 采用的單元測試框架為 jasmine ,測試代碼舉例如下:
- describe('S.mix',function(){
- it('works for simple case',function(){
- expect(S.mix({x:1},{y:1})).toEqual({x:1,y:1});
- });
- });
然后打開啟動測試的 html 文件 即可看到圖6所示的單元測試結(jié)果:
圖6: 單元測試結(jié)果
持續(xù)集成
為了提高測試效率,KISSY 還依賴 travis 平臺和 phamtomjs 進行持續(xù)集成測試。 每次提交代碼都會在 travis 平臺上啟動 phantomjs 來運行 KISSY 所有模塊的單元測試代碼。 如圖7所示:
圖7: travis 平臺上的 KISSY
淘寶應(yīng)用場景舉例
淘寶目前的絕大多數(shù)頁面已經(jīng)采用 KISSY 搭建,這次我選取兩個大家使用比較多的應(yīng)用來介紹下 KISSY 在淘寶的實踐:
店鋪頁面
店鋪頁面是商家店鋪的門戶,除了淘寶頁頭之下都可以由商家自定義內(nèi)容,如圖8所示:
圖8:典型的店鋪頁面
可以看出頁面本身就是區(qū)塊化的組織,在程序內(nèi)部也是分成很多個模塊,例如店內(nèi)搜索模塊,寶貝分類模塊,銷量統(tǒng)計模塊等, 每個模塊負責頁面一塊區(qū)域的交互實現(xiàn),這些模塊又會調(diào)用 KISSY 的模塊來實現(xiàn)自身的邏輯。 而每個商家的店鋪可能使用到的區(qū)塊并不相同,這也意味著每個商家店鋪所用到的程序模塊也不相同。
店鋪模塊與 KISSY 模塊依賴關(guān)系如圖9所示:
圖9:店鋪模塊與 KISSY 模塊的關(guān)系
在實際開發(fā)中配置店鋪應(yīng)用為一個包,其內(nèi)的所有模塊都放入這個包內(nèi),***由頁面初始化腳本加載當前店鋪需要的模塊列表。例如:
- KISSY.use('shop/search,shop/category,...');
在線上會發(fā)出兩個 combo 請求:一個為店鋪頁面需要的應(yīng)用模塊集,一個為 KISSY 自己的模塊集,例如
- http://a.tbcdn.cn/s/kissy/1.3.0/??dom/base.js,event/base.js,overlay.js...
- http://a.tbcdn.cn/p/shop/??search.js,category.js...
寶貝詳情應(yīng)用
寶貝詳情頁面用來展示商家單個商品的詳細信息,評價,成交趨勢等信息,并為下一步購買做準備,是目前淘寶訪問量***的頁面。
該應(yīng)用和店鋪應(yīng)用緊密相關(guān),從頁面可以看出,很多區(qū)塊和店鋪頁面對應(yīng)區(qū)塊相同,實際上在代碼層面也是引用同一份模塊, 首先寶貝詳情應(yīng)用和店鋪應(yīng)用一樣加載當前頁面用到的店鋪模塊,然后再加載這個頁面本身的應(yīng)用模塊。 但是寶貝詳情業(yè)務(wù)本身邏輯十分復(fù)雜,若像店鋪應(yīng)用一樣也是采用模塊 combo 的方式則會導(dǎo)致請求 url 過長, 進而 KISSY 會對過長的 combo url 拆分成多個短的 url,反而適得其反。 因此這里會把寶貝詳情頁自身的模塊打包合并,將自己模塊的主模塊和依賴模塊都合并到主模塊中去, 最終線上會發(fā)出三個請求,其中兩個為 combo 請求,一個為非 combo 請求,例如:
- http://a.tbcdn.cn/s/kissy/1.3.0/??dom/base.js,event/base.js,overlay.js...
- http://a.tbcdn.cn/p/shop/??search.js,category.js...
- http://a.tbcdn.cn/p/detail/main.js
總結(jié)
KISSY 才剛剛處于成長初期,相對于國外成熟框架尚有不小差距,不過依然承受住了淘寶復(fù)雜多變業(yè)務(wù)的考驗。 下一步 KISSY 會繼續(xù)完善基礎(chǔ)組件例如 date,datasource,selector,graphics 等, 重構(gòu)已有組件例如 switchable,calendar 等, 增加 package manager 方便基于 KISSY 模塊的提交與共享,補全測試用例,實現(xiàn)代碼覆蓋率檢測,不斷提高運行穩(wěn)定性。 將來我們堅信 KISSY 會隨著淘寶的發(fā)展而繼續(xù)成長,也會隨著國內(nèi)外前端技術(shù)的不斷發(fā)展而不斷進步。 希望有興趣的你也能加入到 KISSY 開發(fā)中,一起學(xué)習(xí)進步,享受成長的樂趣。
網(wǎng)頁題目:模塊化高擴展性的前端框架KISSY
網(wǎng)站鏈接:http://www.5511xx.com/article/cdodoej.html


咨詢
建站咨詢
