1. 主干列表

2. 前言

- 統(tǒng)帥全軍
首先你的人格不能分裂,別人的意見你要能聽得進(jìn)去,別人可能會(huì)覺得不合理或者什么意見,你要能虛心的接受,而且能從中去改變一些東西,這是你必須要做的,你的架構(gòu)需要得到所有人的認(rèn)可,如果沒有你這個(gè)架構(gòu)就失敗了,有一句話叫做:不能為了架構(gòu)而架構(gòu),而是為了適配業(yè)務(wù)適配人。舉了一個(gè) 地圖 項(xiàng)目的案例從開始的使用 PHP 到后來的為了團(tuán)隊(duì)選擇了 NodeJS,所以說統(tǒng)帥全局需要的是綜合素質(zhì)的自我修養(yǎng),要有軟素質(zhì)和硬能力
- 消息通訊
在我們平時(shí)進(jìn)行開發(fā)的時(shí)候,大家需要注意的是 消息通訊 的機(jī)制,比如說有一種設(shè)計(jì)模式叫做 觀察者--示例來自湯姆大叔,可以監(jiān)聽到別人觸發(fā)回來的這樣一個(gè)事件,比如說: a b 兩個(gè)人,a 做了一件事情,他把這件事情做好之后需要告訴 b,那個(gè) b 要得到這個(gè)消息,你要能編寫這種消息傳遞的組件然后來促進(jìn)整個(gè)團(tuán)隊(duì)在開發(fā)的時(shí)候進(jìn)行這樣的融合;再舉個(gè)例子:做地圖的定位,定位成功了,那么需要定位的其他組件能監(jiān)聽到這個(gè)定位成功,你怎么去釋放呢?用最簡單的方法 jquery 里面的三個(gè)函數(shù) on 、trigger 、off 這三個(gè)函數(shù)就能組成一個(gè)非常經(jīng)典的事件監(jiān)聽器,具體的可以查看上面的 觀察者 鏈接
- 插件隨組
就是說將整個(gè)項(xiàng)目以插件化的形式來生成,比如說:index.html 里面的內(nèi)容就可以是 render 的其他一些模塊的內(nèi)容,可以隨意地去組合,也可以隨意地去替換,這樣可以將業(yè)務(wù)更好的擴(kuò)展
- 本地可調(diào)
有一個(gè)比較專業(yè)的名詞叫做 mock data (模擬數(shù)據(jù)),以前的時(shí)候我們前端調(diào)試代碼就要裝一堆像 .NET 開發(fā)需要的 VS IIS 等等需要啟動(dòng)服務(wù)的東西,會(huì)特別的繁瑣,現(xiàn)在 NodeJS 啟個(gè) server 就非常的方便了,用 webpack 、koa、express 等等都可以了,做前端需要做的是前端方面的容錯(cuò)機(jī)制、接口規(guī)范,這樣可以有很好地用戶體驗(yàn)
- 多端方案
現(xiàn)在的一個(gè)方案如果說隨著你業(yè)務(wù)的擴(kuò)充,一定讓你現(xiàn)在所織構(gòu)的框架能夠去容納多端,就是你開發(fā)的組件是可以隨意地發(fā)布到 Android 、 iOS 甚至是其他硬件(電視)端,所以當(dāng)你選擇這個(gè)技術(shù)框架的時(shí)候,你一定要為了這種多端去準(zhǔn)備,現(xiàn)在有好多技術(shù)都可以支持跨端,比方說: NW ,它可以讓我們的 JS 跨 PC 端,所以一定要為這個(gè)做好準(zhǔn)備,假設(shè)有一天你的客戶端突然需要一個(gè)同樣的組件,這樣就可以直接拿來用,不用再重新去寫了,你要能把這些東西快速的發(fā)布成一個(gè)小的 SDK(軟件開發(fā)工具包),這樣是作為一個(gè)前端架構(gòu)師的準(zhǔn)備工作,把這個(gè)發(fā)布成一個(gè)小的 SDK 就需要有一定的編程基礎(chǔ)了 比如說: Java 。
如果上述的 5 條你都考慮到了,就算是一個(gè)比較優(yōu)秀的工程師了
- 代碼分模
主要就是模塊化,在早期的模塊化有很多的處理方案,比如說:CJS(commonJS)、RequireJS (JavaScript 文件和模塊的加載器)等等,那么現(xiàn)在的分模呢,已經(jīng)到了 ES6、import、萬物皆模塊、webpack 這種的時(shí)代了,你要做的就是把這些東西分清,這些模塊是怎么組合的,比如說:你一個(gè) css、js、html 組成了一個(gè)模塊,這樣也是一個(gè)分模的方法;把所有的 js 組合到一塊,也是一種分模的方法;但是一定要注意這些東西得有一個(gè)非常詳細(xì)的模塊劃分,你需要畫出一張圖告訴你的老大 你的這些代碼預(yù)計(jì)上線之后將來擴(kuò)充所有模塊該是什么樣的,那么你的老大也會(huì)清晰的知道你的能力
- 雅虎軍規(guī)
這個(gè)是面試?yán)锉貑柕膯栴},所有的網(wǎng)站、所有的做這種前端構(gòu)建的時(shí)候?yàn)榈氖鞘裁茨?為的就是,其中一個(gè)是編譯:讓代碼寫的更爽,還有一個(gè)就是讓這個(gè)產(chǎn)品別人用起來更爽,所以呢 雅虎軍規(guī)的目的就是讓代碼上線之后更爽,說白了為了性能的,所有的雅虎軍規(guī)都是為了性能而生的,比如說:把 html 中的 js 文件放到 body 里面怎么怎么的,這就是雅虎軍規(guī)里第一條非常簡單的,就是你要了解整個(gè)網(wǎng)頁,整個(gè)雅虎軍規(guī)有將近二三十條,那么你做這樣一個(gè)前端工具的時(shí)候如果沒有遵循到雅虎軍規(guī),比如說:你用 webpack 把所有的 js 文件都編譯了,然后你會(huì)發(fā)現(xiàn)所有的 script 都把頁面給堵住了,那你這個(gè)架構(gòu)就沒有人會(huì)去認(rèn)可,因?yàn)樯暇€之后性能非常差,所以在做這樣的前端架構(gòu)的時(shí)候一定要去考慮到雅虎軍規(guī),如果你沒考慮到這個(gè)那么前面 6 條你做的基本上就是廢掉的,所以這個(gè)是非常重要的
- 工業(yè)為先
這個(gè)意思就是說:少去做你人肉的去操作,比如說:一般的 html 上線之前要壓縮,那么有很多的壓縮方式,你可以上百度去搜索 html 壓縮 把 html 復(fù)制過去然后壓縮,壓縮好了在復(fù)制回來,這樣一個(gè)就好了,但是這只是一個(gè),如果是成百上千個(gè)肯定不可能再人肉去操作了,所以一定要有一些工程化的東西,為什么會(huì)有 Grunt、Gulp 這樣的東西呢,實(shí)質(zhì)上它們幫助我們做了這些工業(yè)的事,工業(yè)化的前端就是說,它像一條流水線一樣,把我們這些東西塞進(jìn)去然后產(chǎn)出一些東西,那么這就是工業(yè)為先,一定要注意前端的架構(gòu)要保持這種工業(yè)為先的理念,如果說你沒有很好地去利用到當(dāng)前你手頭的編譯工具而是發(fā)現(xiàn)很多東西自己在手動(dòng)的去做那么這個(gè)架構(gòu)也是失敗的
- 持續(xù)可擴(kuò)
我們都知道因?yàn)檫@個(gè)產(chǎn)品變化的節(jié)奏很快,那么一定要注意哪些東西要有這種長遠(yuǎn)的打算,不能說這個(gè)文件夾先這樣吧、把這個(gè)文件夾先扔這吧怎么怎么樣的,你一定要有長遠(yuǎn)的考慮,像是這個(gè)組件可以擴(kuò)展、還有一些公用的文件全都提出去,早早地做打算才能讓你這個(gè)架構(gòu)越來越并發(fā),否則就造成了在國內(nèi)軟件開發(fā)非常嚴(yán)重的問題--重構(gòu),你們會(huì)經(jīng)常發(fā)現(xiàn)項(xiàng)目被重構(gòu)了,為什么呢,就是因?yàn)橹暗暮芏鄸|西沒有想好,沒有做好這種持續(xù)可擴(kuò)的準(zhǔn)備,那么在持續(xù)可擴(kuò)的技術(shù)之前呢,也要做一個(gè)非常重要的東西就是 技術(shù)選型,那么這個(gè)技術(shù)選型一定要具有一定的前沿性,就比如說:你現(xiàn)在的項(xiàng)目用 ES6 ,過兩年可能瀏覽器就普遍了,現(xiàn)在我們用 babel 編譯,將來呢就不需要 babel 編譯,可以直接扔到線上了,這個(gè)就是持續(xù)可擴(kuò)一個(gè)非常經(jīng)典的例子
- 一鍵部署
這個(gè)需要去了解運(yùn)維,之前也了解過像 LVS(Linux虛擬服務(wù)器)、Keep-Alive 等等這些的東西,因?yàn)閷砟阋涯氵@個(gè)項(xiàng)目實(shí)際的放到線上去,運(yùn)維工程師不了解前面的 9 條前端架構(gòu)師干的活,他是負(fù)責(zé)把服務(wù)器做好,不讓你的服務(wù)器崩掉,怎么在服務(wù)器上取這些服務(wù)需要靠你 一鍵部署,我們可以用 Yeoman 或者是其他的工具去做,比如說:你用一個(gè) Grunt 定義一個(gè) default tast(默認(rèn)的任務(wù)),只要你執(zhí)行一個(gè)
grunt項(xiàng)目就編譯完了,然后用一句 shell 腳本 把這個(gè)項(xiàng)目 SEP 到本地 再到遠(yuǎn)程服務(wù)器,遠(yuǎn)程服務(wù)器自動(dòng)刷新系統(tǒng)給你一分,這樣就完了,但是前提是你一定得按你當(dāng)前這個(gè)目錄把整個(gè)一個(gè)網(wǎng)站全部搞定,就是說運(yùn)維他不懂你這個(gè)前端到底都干了些什么 ,所以說你給運(yùn)維一個(gè)命令讓他發(fā)布成功,這個(gè)項(xiàng)目就算是 OK 了
上面這 10 條只要你能理解透了,那基本的面試官就難不住你了
3. 初入江湖

在你剛成為一個(gè)前端工程師的時(shí)候,你需要做的事情就是:壓縮
文件 MD5 就是給它加一個(gè)戳,我們平時(shí)會(huì)看到有人在 link 一個(gè) a.css 的時(shí)候,后面會(huì)加一個(gè) ? 什么的,比如說 a.2015 什么的,這個(gè)跟這個(gè)戳差不多,主要是為了不讓這個(gè) css 文件在本地有太多的緩存,這個(gè)是早期的用法,但是現(xiàn)在都做的是這種 MD5 的比較,給這個(gè)文件值后面加這么一堆 ,比方說:a.554.js 下次上面就變成了 a.5644.js ,這樣上一個(gè)文件就不會(huì)被緩存調(diào)了,這些都是最基礎(chǔ)的東西了


tinypng 是一個(gè)壓縮圖片的網(wǎng)站
慢慢的你就會(huì)使用一些簡單的框架實(shí)現(xiàn)像后臺(tái)管理這樣的簡單項(xiàng)目
4. 深不可測

接下來你會(huì)發(fā)現(xiàn)有很多的東西還不是很夠用,隨著需求的增加你的代碼變得越來越亂,因?yàn)樯畈豢蓽y的原因是你的產(chǎn)品和需求在不停的迭代,所以你會(huì)發(fā)現(xiàn)很多東西都比較的混亂無章

深不可測還有一個(gè)原因是,你原來在頁面里面寫單個(gè)的 html 會(huì)寫無數(shù)的 ajax ,比如說:你可能寫六個(gè)或七個(gè)為了業(yè)務(wù)的需求,這個(gè)時(shí)候如果在移動(dòng)端就會(huì)造成 ajax 直接就斷掉了,因?yàn)樗l(fā)的 ajax 是有限制的,在你請求這個(gè) ajax 的時(shí)候,請求就把你干掉了,還有是網(wǎng)絡(luò)不好的情況下,就死掉了,請求發(fā)了十幾個(gè)也就不行了

然后就是單個(gè) js ,就比如說: index.js 一直寫越來越大 越來越大 這樣也是一個(gè)問題

然后就是重復(fù)加載,比如說:你的每個(gè)頁面都會(huì)引這個(gè) a.js 就會(huì)造成這個(gè)問題
image.png
會(huì)發(fā)現(xiàn)項(xiàng)目中 到處都是 $.ajax function

domready 是一個(gè)非常重要的指標(biāo)

如果你還是用的 css 來寫,沒有引進(jìn) sass 或者 less 其他的一些東西,那么你會(huì)發(fā)現(xiàn)在適應(yīng)不同設(shè)備的時(shí)候,自己要寫很多的 css

就是說之前將 a.css 和 c.css 兩個(gè)頁面的 css 合并在了一起,但是后來 a.css 對(duì)應(yīng)的頁面不要了,但是 css 還是之前合并在一起的,這樣就是一種資源的浪費(fèi)


上述的問題都是一些在企業(yè)中遇到的一些不可避免的常見性問題。
下圖這些就是上面的很多問題的一些解決方法

- BACKBONE.JS
是一個(gè) MVC 的解決方案,把代碼分成對(duì)應(yīng)的區(qū)塊,不把所有的代碼放在一個(gè)里面了,分成 m(model) v(views) c (controller)
- Underscore.js
可以硬生生的幫我們?nèi)テ?html ,比如說我們從后臺(tái)取回來一個(gè) json 對(duì)象,然后 for 生成一大堆的 table 追加到頁面里,這樣有了 Underscore 之后可以提前在頁面里寫好這個(gè) table ,然后把后臺(tái)的變量 灌進(jìn)去他自己就會(huì)拼,這樣就不用 js 再去做了
- Sea.js
可以讓我們所有的 js 按照模塊化的方式去處理
- Less 或者 Sass
會(huì)讓我們所有的 css 像編程一樣,有各種各樣的模式去用
- pushstate + ajax + hash
pushstate 可以讓 url 變,但是頁面不切換,pushstate 可以使路由變?nèi)缓箜撁娌蛔儯倥浜?ajax 做一個(gè)單頁的系統(tǒng),這樣就可以節(jié)省掉很多很多
上述的五個(gè)方法雖然解決了一些問題,但是還是有解決不了的

剩下了三個(gè)問題

但是這個(gè)時(shí)候出現(xiàn)了一個(gè)非常嚴(yán)重的問題,你會(huì)發(fā)現(xiàn)前面的 js 邏輯越來越多,引了很多的庫,加載頁面的時(shí)候會(huì)一直 loading 加載你引得一堆的庫

帶來的問題就是

這個(gè)時(shí)候還要考慮到各種各樣的終端設(shè)備
image.png

4. 返璞歸真

smarty(php)
上面的這些方面是直接將后臺(tái)的變量渲染到頁面里了,就像早期的 asp .NET 控件,可以把一些東西直接拖到控件里,我們可以先把一些主要的東西直接通過我們的模板去給他生成,把 js 的東西相當(dāng)于后移,不讓頁面對(duì) js 有太大的依賴了,比如:現(xiàn)在我們的項(xiàng)目中有一個(gè) layout - > 相關(guān)的配置,但是模板的東西也不能太重,如果把所有的信息都渲染到模板里那等待的時(shí)間就長了,需要等待后臺(tái)的處理,所以后臺(tái)輸出多少 留給前臺(tái)多少 需要你對(duì)業(yè)務(wù)的一個(gè)把量的,比如說:后臺(tái)只要輸出頂部剩下的留給 ajax ,那么這個(gè)就要看你真正的怎么去對(duì)待這個(gè)項(xiàng)目了,然后去拆分這個(gè)項(xiàng)目

這個(gè)回到我們前端我們可以不通過后臺(tái),直接用 NodeJS 以及上圖的其他一些框架來實(shí)現(xiàn)
5. 破繭成蝶

如果是上面的東西你都可以自行去解決了,就說明你的技術(shù)已經(jīng)不錯(cuò)了
image.png

當(dāng)你發(fā)現(xiàn)自己可以造出來一套前端框架的時(shí)候,你可以去看下 FIX 、Yeoman、yogurt 或者其他的組裝框架,看下人家的源碼,他們是怎么做的,什么測試吖什么的一套項(xiàng)目完整的流程
那么把這些所有的零散的技術(shù)結(jié)合到你的項(xiàng)目里邊完成最終的 test ,這個(gè)就是你的終極的目標(biāo)了,也就是說能做一套對(duì)當(dāng)前的項(xiàng)目自動(dòng)壓縮、打包、合并、處理好路由、處理好組件、處理好性能,那這樣就成功了

- 自動(dòng)化性能檢測平臺(tái)
這樣可以收集到前臺(tái)的用戶的信息,你能知道你的項(xiàng)目在每分每秒有什么樣的這樣的階段:首頁加載多長時(shí)間、某一個(gè) js 耗時(shí)多久,誰耗時(shí)了,為什么耗時(shí)了,哪個(gè)模塊引用了這個(gè) js ,這個(gè)時(shí)候就需要你有一定的算法知識(shí),把這些東西收集回來
- 自動(dòng)化控制高清圖
有些東西要做到自動(dòng)化的控制高清圖,比方說:我們有 1倍 2倍 3倍或者是其他的圖,適配(在頂部加一個(gè)縮放比率),比如像淘寶的那種高清適配,這些東西都是需要考慮自動(dòng)化的
- 自動(dòng)化 inlinecss js
還有一些 js css 給它們加一些尾綴,比方說:是把這個(gè)加成 inline 還是 outline ,加到內(nèi)部還是外部這些都是需要自動(dòng)化去處理的
- 自動(dòng)化功能測試平臺(tái)
這個(gè)可以防止和 QA 撕,還有就是把自己的東西,如果是在 github 上有非常多的 start 或者是 flow 的話一定要對(duì)你的項(xiàng)目負(fù)責(zé),但是這個(gè)不一樣,這個(gè)是實(shí)際的生產(chǎn)項(xiàng)目,你要做很多的 keys ,真正的交給 QA 之前要通過你自己的 自動(dòng)化功能測試平臺(tái) ,如果說你把這個(gè) 自動(dòng)化功能測試平臺(tái) 做了出來,讓公司大大提升了項(xiàng)目的效率和減少了 QA 的測試時(shí)間,那么這個(gè)也是體現(xiàn)到了架構(gòu)師真正功能的地方
總結(jié):實(shí)際上,后面來的人只要按照指定的區(qū)塊添東西,剩下的你來統(tǒng)籌全局,這樣你在公司的地位、工資自然就高了,從進(jìn)入到一家公司到把這樣的東西產(chǎn)出,你也要去抓時(shí)機(jī),而且要找一個(gè)好項(xiàng)目,尤其是在大公司就業(yè)的時(shí)候一定要選一個(gè)好項(xiàng)目,如果你的項(xiàng)目很爛,那你這個(gè)人也會(huì)慢慢地爛下去了


