年終總結結果到這個時間才寫,其實也是無奈。原本計劃過年寫的,沒想到Steam居然開了個農曆春節特惠,而後就被各類遊戲打了,辣雞平臺,斂我錢財,頹我精神,耗我青春,害我單身前端
如下全都是我的見解,若是有不認同的地方,請大吼一聲「傻逼寫的啥」而後關閉頁面node
本命年終於快過去了,不知道是否是由於沒有穿紅褲衩,這一年有不少不順心的事情,不過也有不少好事。這一年最重要的事情就是順利從一隻學生狗轉職爲一隻社畜。四月份畢業以後之前端工程師的職位入職天貓,到如今也差很少工做一年了。這裏寫一下幹這行以來對於「前端」這個行業的見解和感悟。python
前端工程師在校園裏是一個複雜度和地位都被嚴重低估的職位。老師們對發展迅猛的前端技術不夠了解,更是有很多「師兄師姐」在介紹本身找工做經驗時「xx天速成就找到一份前端工做」、「公司招聘前端也不問會什麼,就問你肯不願踏實幹這行,肯幹進去再教你」。固然學校裏的項目裏也會有頁面,但因爲老師和學生對前端各類技術的陌生,大多數都是使用jQuery堆積代碼完成功能了事。在你們眼裏,寫頁面沒啥技術含量。react
前端的不少基礎知識,都沒法在學校學到。學校老師交給學生的大多都是基礎知識,好比算法、數據結構、編譯原理、操做系統、計算機網絡這些,而針對於特定領域就不多涉及了。見過學校開設C、C++、Java、PHP等語言的課程,卻歷來沒有看到過開設JavaScript、CSS、HTML的課程。網頁設計的選修課卻是有(我報了,很遺憾整個教室只有20人不到),但這裏所謂的網頁設計並非前端那一套技術棧,而是Dreamweaver使用入門。前端技術棧在校園裏沒有普及。webpack
就這樣產生了一個頗有意思的現象:大堆公司喊缺前端,而學生們並不知道前端是什麼,怎麼去學習前端知識(最近兩年稍微好點了),他們更多的是去學Java、C++,走着師兄師姐們走過的道路。有幸如今已經有百度這種大公司注意到了這點,到高校裏開了很多前端知識講座,還在GitHub上搞了培訓項目。nginx
但願各個大公司的前端部門可以更多的走進校園,給對前端感興趣的小朋友們一點指導。git
去年上半年4月份入職打雜了一段時間以後,就開始學習React而且進行了一些實戰演練:github
產出一篇文章輕鬆入門React和Webpack,意外的很受好評,segmentfault上超過了200的收藏,tmall的github博客上也有很多評論。惋惜如今文章中已經有不少不適用了,babel大版本到6發生了很多變化,本地調試也改爲中間件了web
把本身的博客lingyu.wang改爲了全React實現,代碼在這裏,用react-router作了個單頁面應用,底層依然基於hexo,本身給hexo寫了個generate插件把全部數據生成json而不直接生成頁面,爲了練手已經喪心病狂了,SEO什麼的徹底不在意算法
寫了一些腳手架和組件,亂七八糟參見玩具箱
因爲負責天貓最複雜的前端應用之一的開發和維護,有很多老代碼,也因爲遷移成本太大沒有辦法在Java層上插入Node.js中間層,各類模塊之間各類耦合,中間也寫了篇用React作重構時的一些思考。當時項目裏存在如下幾種耦合:
最蛋疼的就是壓根就沒有模塊化,全部代碼都在一個文件裏,2k+行的jQuery那種。最老式的寫法,也是在學校項目裏看到最多的方式,選擇器拿到DOM而後操做綁事件,大多多年前的代碼或者是後端兼職寫的。基本上沒有可維護性。解決這種基本上就靠推倒重寫了,考慮投入產出比看懂它的成本還不如從新寫一個來得快
稍微好一點的是增長了模塊化,但模塊內部和以前思路沒什麼區別,只是把上面那種代碼分開多個文件放了。不一樣的模塊在模塊內部操做相同的HTML,一旦其中一個模塊改變了HTML結構,其餘模塊直接就bug了...
再好一點增長了前端模板引擎,各個模塊都在內部使用模板引擎渲染本身的HTML,模塊初始化傳入一個容器,只要容器不衝突,模塊之間就不會基於HTML耦合。模塊會暴露一些接口,經過模塊管理器獲取實例相互之間直接相互調用,這樣依舊是強依賴,兩個模塊互相依賴,一旦其中一個換了,接口變了,另一個模塊也須要改變本身的代碼。
模塊內部徹底黑盒,只要一個容器,裏面的內容由模塊本身控制。模塊有數據的入口和出口,入口就是一些由父模塊或頁面傳入的配置,出口則是一些由父模塊或頁面傳入模塊回調函數,回調函數裏面附帶傳出的數據,而HTML相互之間沒法互相修改,改了就報錯。沒錯這就是React
最後重構的方案定下來是React+AMD+Gulp(你沒有看錯,沒有打包,沒有webpack),之因此不打包主要是有老代碼,組件頁都沒發佈到npm上,並且因爲阿里的CDN支持combo,因此也就不作打包了,至於使用React作重構,主要是因爲如下幾個緣由:
使用React實現的模塊和組件徹底黑盒,Web Component理念,標籤使用方便快捷。不會引入新的維護成本
組件容易抽離,造成沉澱。我曾經把一部分新業務使用React實現,其中的很多組件稍加完善就沉澱出一些基礎組件,沒有剝離成本
模塊相互之間不會污染,沒辦法直接修改其餘模塊的DOM,改了就報錯,而後QA就提着刀殺過來了
商家應用,容許全異步,富交互功能型頁面,性能不太爛都能接受
目前新業務已經徹底基於React開發,組件庫也基本上沉澱出來了,而老業務也在經過一次次需求像React遷移
我的比較傾向於徹底區分模塊和組件這兩個概念。組件是徹底沒有業務邏輯的功能單元,好比下拉框啊、日期選擇啊這種,組件只專一自身的功能。組件可能會有嵌套,但當發生了嵌套時,對外就是一個組件,父組件內部的子組件對外將徹底不可見,它的行爲也將徹底由父組件控制。組件是複用的單元,應當更多的造成沉澱。而模塊則包含業務邏輯,同時模塊還承載了一個比較重要的功能:和其餘模塊通訊。
因此大致上一個應用就是:應用被劃分爲多個業務模塊,這些模塊邏輯上是扁平的,他們採用統一的通訊機制進行通訊,一個模塊上的數據發生變動時,會通知一個全局的通訊中心,採用pub-sub機制將數據遞交給其餘模塊,其餘模塊拿到數據後影響本身的渲染。模塊內部使用了不少的組件,但模塊內部全部渲染使用的數據都由模塊直接進行管控,樹形傳遞給各個組件。能夠這麼想,模塊內部相似Redux實例,而頁面上有多個Redux實例,它們再經過一個統一的pub-sub中心進行通訊。爲何不整個應用直接作一個Redux實例呢?主要是由於要考慮到跨BU合做和新老多種技術兼容。模塊內部想怎麼玩怎麼玩,能夠是React實現,可使Vue實現,能夠是原生js實現。模塊做爲一個通訊單元只要符合統一pub-sub通訊接口便可。
這套理念也確實實現而且落地到了很多頁面中,但這樣玩顯然還不夠過癮。React終究是前端在玩,前端寫React組件、模塊和頁面很爽,可是數量大了同樣要加班同樣爽不起來。這裏就在考慮有沒有可能下降門檻,把事情交給別人來作,好比後端。首先組件確定是前端來寫了,沒多少後端能寫好前端組件的,若是能寫好,他就不是後端而是全棧了,這種人就應該果斷拉過來幹前端堵缺口。那麼有沒有可能把模塊和頁面交給他們來寫,而前端只提供一些組件呢?
讓後端寫,最重要的一點就是給模板賦能,畢竟後端只能接觸到模板。這麼一想,這不特麼就是React和MVVM相結合麼,把React的Virtual DOM或者說JSX標籤和MVVM的DOM模板同樣寫到HTML上,多麼Web Component化啊。這裏說一下爲何不直接用MVVM好比Vue,而是用React。MVVM確實對後端開發工程師很友好,但這些組件是咱們日常開發前端應用(前端部分前端本身負責的複雜業務)時沉澱下來的,這麼一大批組件讓咱們再去重寫一份MVVM的太蛋疼了,後期維護兩份也比較吃力。就這樣開始嘗試,通過一段時間調研後,發現react-templates,能夠把模板字符串轉化爲React.createElement
,當時用browserify給它打了一個包,尼瑪壓縮後好像有500K+(未gzip),它是針對Node.js的。因而乎把它整個代碼大致上進行了重寫,移除了lodash,本身重寫了使用的一些工具方法,而後又重寫了模板解析部分,採用瀏覽器的XML解析器,又移除了esprima等語法校驗,而後又加了一堆定製化,最後壓縮後20K左右(未gzip),終於能夠在頁面上用了...最後大致上就實現了一套這樣的方案:
一堆平常沉澱的React組件
一個全局的pub-sub通訊工具負責模塊的通訊
一個React實現的Module負責充當模塊的角色
Module內部使用React Templates字符串模板編譯成Virtual DOM的函數來進行渲染,能夠經過一些「控制指令」來控制渲染結果,組件上面能夠經過一些「通訊指令」來遞交組件的數據給Module這個模塊。而Module模塊數據發生變動後會觸發整個模塊重繪,數據又會從新傳遞下來給組件並變動組件的渲染結果。
Module外部則是經過全局的pub-sub通訊工具來負責模塊通訊,Module負責與這個通訊工具進行直接交互來進行數據通訊。通訊創建橋接的方式也是在Module上定義一些「通訊指令」
最後,整個系統都採用React Templates來實現,整個頁面實現和通訊所有寫在模板上,頁面上只有一堆組件(能夠在模板裏動態require,模板會在編譯期提取而後拉取完成了才進行初始化)。沒有任何業務js邏輯存在。
這樣實現了好幾個頁面我已經成功上線跑了幾個月了,還有幾個正在實現中,看上去很美好。但後來仍是發現了一些問題:模塊通訊過程太複雜,一個完整的數據流轉過程經過指令很難很直觀的展示,一個看起來很簡單的交互中間可能會通過4-5步數據流轉,甚至包括一些alert、confirm等等,想讓後端寫不太可能,連其餘前端都看不太懂數據如何流轉。這一塊還有太多能夠優化的地方。
去年下半年我參與了部門統一使用的前端流程自動化工具的維護及改造,同時負責了商家端通用組件的腳手架的開發和維護。花了很多時間在前端流程自動化上。前端通過這麼多年的發展,頁面上承載的交互、功能、邏輯不斷增長,項目逐漸變得龐大,維護和開發成本也隨之增長,但依然招不到人。__這裏順帶打個廣告,若是想來天貓前端的請發郵件至lingyucoder@gmail.com__。流程自動化也就愈發重要。最理想的情況就是,只要是機械可以完成的工做,人就不要參與了。用一些腳本代替簡單重複的勞動,這樣咱們也就能夠少加點班了。
Node.js給前端開發流程自動化帶來了福音。從目前部門前端開發流程來看,主要就是如下幾個步驟,括號裏是對應的開源工具:
建立項目(Yeoman)
構建以及監聽文件變化自動構建(Gulp、Webpack、Grunt,Grunt估計如今用的不多了)
本地調試,資源代理(Koa、Express+各類定製的中間件)
自動化測試、代碼覆蓋率測試(mocha、istanbul、should/chai/expect、phntomjs、karma)
文檔自動化生成(本身基於AST提取,或者直接用jsdoc之類的工具)
自動化校驗、發佈(一些腳本)
這裏主要聊聊構建、本地調試和自動化測試
如今的構建過程已經再也不像之前那樣壓縮一下就簡單,構建過程當中每每會拿代碼生成語法樹而後作各類操做:
Babel爽爽寫ES6甚至ES7
將代碼中的註釋轉化爲監控打點(istanbul我記得就是基於語法樹給每一個語法分支包一層打點層,彙總數據)
將代碼中的註釋提取生成文檔(React組件自動生成props文檔就是這種方式)
將commonjs規範的代碼轉化爲各類各樣的模塊化解決方案(AMD、KMD、UMD等等)
提取模塊間的依賴關係,梳理應用模塊依賴關係,繪製模塊依賴樹
Webpack打包
各類語法檢查(eslint,jshint),有時候還會有一些定製化的校驗
...
如今你們都比較中意webpack,依賴打包使得資源請求數大幅度減小(使用不支持combo的CDN服務的公司確定很開心)。我我的仍是對於webpack有一些顧慮,主要有兩點
不太贊同瀏覽器內使用的資源也發佈到npm上。瀏覽器上和Node.js通用的代碼可能也就不到5%(lodash啊,underscore啊,moment啊這種),在npm上找到一個模塊還要確認到底哪一個場景下可用。使用的即使是這些能夠共用的庫,也會有一個很蛋疼的問題:Node.js的模塊每每大而全實現儘量多的功能,而頁面使用的模塊則是儘量小而美,資源加載量儘量少。好比只用到時間格式化和反格式化就引入一整個moment(moment真特麼大,我通常就格式化反格式化,喜歡用fecha),對於Node.js也許沒什麼壓力,但對於頁面就很蛋疼了。如今rollup試圖解決這個問題,仍是比較值得看好的
不一樣版本重複打包的問題。這個問題比較頭疼。若是一個項目依賴了兩個組件,而這兩個組件引用了一個庫的兩個不一樣版本,這個庫就會被打包兩份,因而乎代碼量就duang一下增大了。目前依舊沒有看到比較好的方式來解決。雖然能夠用peerDependencies對一些基礎庫(好比React這種)作一下處理,也只是緩解一些罷了。
另外吐槽一句,webpack配置真繁瑣啊,我的目前傾向的方案是使用webpack+gulp,webpack負責打包和構建,其餘的工做依舊交給gulp,我喜歡stream(不是steam)
前端資源本地調試其實挺簡單的,就是把線上使用的資源代理到本地資源。因爲如今通常都會使用CDN來承載這些資源(若是大家公司不用CDN,請找大家老闆撥點經費買個CDN服務吧),大體上也就是幾個步驟:
把CDN的域名經過host指向本地
在本地80(HTTP)或443(HTTPS)端口開啓對應的代理服務,根據請求查找本地資源返回
若是涉及須要開啓多個服務,將各個服務開在不一樣的端口後在80或443端口加個nginx層作轉發
目前部門裏面用的是Koa+中間件實現了這裏面全部的內容。Koa如今也2.0了,使用新版本的Promise的co,用起來仍是很爽的
若是一旦涉及到本地模板的調試,就很蛋疼了,基本上是模擬數據,這裏懶得扯了。
對於自動化測試這一塊,在學生時代一直以爲測試麻煩,沒啥收益。但實際上自動化測試對於開發效率提高很大。以前參與部門統一構建工具的改造,有任何修改就跑一遍測試用例和代碼覆蓋率,效率很是高,還很是容易造成沉澱,一旦有bug,就把bug會發生的場景也作成一個測試用例,方便後人接手。並且把代碼接入像travis這樣的持續集成平臺後,代碼質量更有保證了,任何一次push都會自動觸發測試,即使是pull request裏的代碼也能夠保證質量。如今寫代碼覆蓋率低於90%就以爲各類不爽,必定要提到90%以上。
對於Node.js的模塊,測試很方便,除了命令行工具可能須要加像sinon這樣的模塊來監聽stdio之外,其餘的基本上都能直接在代碼中模擬環境。因爲我的寫Node.js代碼喜歡拆分的很細,每一個邏輯單元都用co、curry作包裝,因此特別喜歡使用mocha+should,should 8.0+直接支持Promise,爽歪歪,
對於瀏覽器裏跑的代碼,測試和覆蓋率就比較麻煩了,首先模擬環境比較蛋疼,大體上3種方案:
構建一個測試頁面,人肉直接到虛擬機上開各類瀏覽器跑測試頁面(好比f2etest),這個問題就是很差持續化集成,人肉工做較多
使用phantomjs構建一個僞造的瀏覽器跑單元測試,大體上就是先用gulp-istanbul給代碼打點,而後拿mocha-phantomjs跑包含測試用例的頁面,最後經過hook拿到結果用istanbul生成可視化的覆蓋率頁面,蛋疼就是phantomjs畢竟是Qt的webkit,不是真實環境,phantomjs也是各類坑
經過karma調用本機各類瀏覽器進行測試,這個如今還沒玩的很6,還在研究中。仍是有很多問題沒解決,畢竟用的mac,去哪兒找IE 8,囧,更別說移動端那麼多機型
對於測試我的一直堅持一個觀點:基於投入產出比來作測試。因爲維護測試用例也是一大筆開銷(畢竟沒有多少測試會專門幫前端寫業務測試用例,而前端使用的流程自動化工具更是沒有測試參與了)對於像基礎組件啊,基礎模型啊之類的不常變動且複用較多的部分,能夠考慮去寫測試用例來保證質量,但對於迭代較快的業務邏輯以及生存時間不長的活動頁面之類的就別花時間寫測試用例了,維護測試用例的時間大了去了,不如喝杯茶冷靜下讓QA他們去測吧。
這一年因爲轉職社畜各類忙的要死,致使沒有多少時間靜下心來看書了,文章也寫得少了。因而更傾向於天天水一水個人github(中間一大段空白由於3DS到貨了,鏖戰怪物獵人4G,這遊戲真特麼好玩),寫一些腳手架啊、組件啊、小工具啊啥的。以前以爲一些開源的logger很差用,就本身寫了個linglog,以前負責一個業務變動比較多老是打tag發佈,就寫了個自動發佈程序publishy,它會在發佈前作一些校驗防止我沒有commit或者沒有add之類的。還有像React組件自動化提取props作文檔弄了個react-prop-table,以及對應的配套的markdown內容段自動更新gulp插件gulp-insert-md。對應還有一些less依賴關係解析啥的弄了less-tree,而後有個需求要在模塊更新時自動輸出最新更新有哪些變更因而有了changelogy,而後還有幾個本身弄得帶單元測試、代碼覆蓋率測試、travis持續集成、eslint等的腳手架:React組件腳手架generator-lingyu-react-component, Node模塊腳手架generator-lingyu-node-modules, gulp插件腳手架generator-lingyu-gulp-plugin, 命令行工具腳手架generator-lingyu-cli-modules。寫這些玩意過程當中學到了很多Node.js的姿式,雖然離一個真正的Node.js工程師差的太遠
另一點是入職後全面從sublime切到atom了,python苦手仍是傷不起,咱用atom有插件需求找不到本身寫一個,好比以前給xtemplate模板寫了個atom語法高亮和snippet插件atom-language-xtpl,感受比以前用sublime爽多了
還花了點錢買了SnippetsLab這個軟件,用來放一些代碼片斷超好用,我在裏面放了很多本身日常寫的一些小的工具函數,好比clone啊,unique啊,param和unparam啊這種,須要的時候就搜一下複製出來,方便快捷
今年玩的遊戲很少,由於3DS到貨了,先說幾個3DS遊戲:
怪物獵人,沉迷了一段時間,甚至一成天一成天的和各類龍作鬥爭。如今怪物獵人累計遊戲時間應該有250小時了...
口袋妖怪X:硬着頭皮啃英文,擼寵系統好棒,天天擼一擼本身的寵,看到他們開心的樣子本身也開心。通了一週目就懶得啃英文了
牧場物語,在同事推薦下玩了,模擬經營農場,種菜、種果樹、養各類動物賣錢...玩了幾十個小時吧,玩不下去了...後面天天刷牛擠牛奶,擼雞一天就結束了...沒領悟到遊戲的樂趣
路易吉鬼屋,超級瑪麗裏的弟弟被拉到鬼屋裏探險的故事,樂趣就是看路易吉這個大寫的慫貨被各類鬼嚇尿...解密遊戲,其實挺好玩的
馬里奧賽車:和跑跑道具賽差很少,玩道具賽,道具比較少,賽道也少,難度也低。
勇氣默示錄:回合制RPG,還在龜速通關中,畫面很棒,3D的人物很Q,至關不錯的遊戲
而後說一些PC的:
俠客風雲傳:情懷!絕對的情懷!做爲一個當年武林羣俠傳的狂熱愛好者,俠客風雲傳我通關了至少6次,乞丐、東廠、盟主、霸圖、天王各類都通了一遍。湘雲仍是一如既往的女神,但願徐大早日重製金庸羣俠傳
仙6:這個戰鬥系統特麼什麼鬼...沒有玩下去的動力啊
堡壘(bastion):很精緻的遊戲,畫面惟美,歌曲好聽,劇情不長但很好玩。
進化之地2(evoland2):尼瑪一個遊戲能這麼玩我算是長見識了,集DQ、塞爾達傳說、超級瑪麗、拳皇、雙截龍、炸彈人、遊戲王、洛克人、1943等等於一身的遊戲也沒誰了
阿瑪拉王國:和老滾有點像,不過比老滾有打擊感,重要的是有WOW那種裝備系統。老滾的裝備系統是個鬼...惋惜沒有老滾那麼多mod,畢竟少女卷軸
饑荒:這遊戲太特麼難了,一到冬天就死...得找個大神帶我
春節剁手買了昆特牌3和龍騰世紀,有時間玩一玩。最後重申一句:辣雞平臺,斂我錢財,頹我精神,耗我青春,害我單身
看他們的總結都有這個,因而我加上了
光棍年數++
前端發展太快,要學的太多。原本去年計劃學React Native的,結果只寫了個Demo...Electron也是隻跑了個HelloWorld...Node.js的服務器也只是搭了個簡單的...canvas也是隻寫了一些小Demo。但願新的一年技術不掉隊,可以多學點這些以前想學沒學的東西。另外但願可以沉澱出本身的組件庫,之後快速搭建一個頁面也方便一些