一、綜合1.一、適用場景:1.二、核心思想:1.三、切入角度:1.四、其餘二、基礎層設計2.一、自建Gitlab2.二、版本管理2.三、自動編譯發佈Jenkins2.四、純前端版本發佈2.五、統一腳手架2.六、Node中間層2.七、埋點系統2.八、監控和報警系統2.九、安全管理2.十、Eslint2.十一、灰度發佈2.十二、先後端分離2.1三、Mock2.1四、按期備份三、應用層設計3.一、多頁和單頁3.二、以應用爲單位劃分前端項目3.三、基礎組件庫的建設3.四、技術棧統一3.五、瀏覽器兼容3.六、內容平_臺建設3.七、權限管理平_臺3.八、登陸系統設計(單點登陸)3.九、CDN3.十、負載均衡3.十一、多端共用一套接口
css
我在2年以前,寫過一篇中小型項目的前端架構淺談。隨着能力的上升,以及在阿里巴巴工做的經驗,是時候寫一篇大型項目的前端架構分析了。html
本篇文章不會更多側重於具體技術實現,而是嘗試從更高角度出發,分析爲何要這麼作,這些設計能解決什麼問題,成本和收益如何。前端
因爲做者能力有限,可能會有所缺漏或者部分錯誤,歡迎讀者指出。vue
本篇文章,適用於單個/多個大型項目、擁有超過10個以上的前端開發的場景。react
前端項目的規模不一樣,成本收益比也會有所差異。一般來講,人員越多、項目複雜度越高,那麼收益/成本的比值越大。git
對於人數較少、項目簡單的開發團隊,可能有部分措施不適用,所以應該根據具體狀況來選用。web
【1】解決問題:前端架構的設計,應是用於解決已存在或者將來可能發生的技術問題,增長項目的可管理性、穩定性、可擴展性。面試
【2】人效比:對於須要額外開發工做量的事務(本文中存在一些須要必定開發量的內容),咱們在決定是否去作的時候,應該考慮到兩個要素:第一個是花費的人力成本,第二個是將來可能節約的時間和金錢、避免的項目風險與資損、提升對業務的支撐能力以帶來在業務上可衡量的更高的價值、以及其餘價值。ajax
【3】定性和定量:架構裏設計的內容,必定要有是可衡量的意義的,最好是能夠定量的——便可以衡量帶來的收益或減小的成本,至少是能夠定性的——即雖然沒法用數字闡述收益,但咱們能夠明確這個是有意義的,例如增長安全性下降風險。chrome
【4】數據敏感:專門寫這一條強調數據做爲依據的重要性。當咱們須要說服其餘部門/上級管理者,以推進咱們設計的內容時,只有數據——特別是跟錢有關的數據,纔是最有說服力的證實。
因爲篇幅所限,本文很難直接給出定量的值,所以建議架構設計者,先確保項目中設計使用2.7裏的埋點系統,根據埋點系統獲取的數據,對項目效果進行定量分析,並以此寫成PPT和其餘部門/上級管理者進行協調。
分爲基礎層和應用層。
基礎層偏基礎設施建設,與業務相關性較低。
應用層更貼近用戶,用於解決某一個問題。
部分兩個都沾邊的,根據經驗劃分到其中一個。
因爲已經談到架構層級,所以不少內容,並不只僅只屬於前端領域,有不少內容是複合領域(前端、後端、運維、測試),所以須要負責架構的人,技術棧足夠全面,對將來發展有足夠的前瞻性。
文章的內容結構爲:【項目】—>【解決的問題和帶來的好處】—>【項目的實際意義】
這個是基礎的基礎了。本不該該提的,不過考慮到我最近面試的幾家公司,有的公司(人數並很多)並無使用Gitlab,所以專門提一下,而且使用這個的難度很是低。
強烈建議使用Gitlab進行版本管理,自建Gitlab難度並不大,方便管理,包括代碼管理、權限管理、提交日誌查詢,以及聯動一些第三方插件。
意義:
公司代碼是公司的重要資產,使用自建Gitlab能夠有效保護公司資產。
版本管理的幾個關鍵點:
發佈後分支鎖死,不可再更改:指當例如0.0.1版本成功發佈後,不可再更改0.0.1分支上的代碼,不然可能會致使版本管理混亂。
全自動流程發佈;指應避免開發者提交後,手動編譯打包等操做,換句話說,開發人員發佈後,將自動發佈到預發佈/生產環境。開發人員不和相關環境直接接觸。實現這個須要參考下面的2.3。
多版本並存;指當例如發佈0.0.2版本後,0.0.1版本的代碼應仍保存在線上(例如CDN),這樣當出現線上bug時,方便快速回滾到上一個版本。
意義:
提升項目的可控性。
這個工具用於在代碼發佈後,執行一系列流程,例如自動編譯打包合併,而後再從Gitlab發佈到CDN或者靜態資源服務器。
使用這個工具,可讓通常研發人員不關心代碼傳到Gitlab後會發生什麼事情,只須要專心於開發就能夠了。
意義:
讓研發人員專心於研發,和環境、運維等事情脫鉤。
純前端版本發佈分爲兩步:
前端發佈到生產環境——此時能夠經過外網連接加正確的版本號訪問到新版本的代碼,但頁面上的資源仍是舊版本;
前端經過配置工具(或者是直接更新html文件),將html中引入的資源,改成新版本。
解決的問題是:當前端須要發佈新版本時,能夠不依賴於後端(根據實際狀況,也能夠不依賴於運維)。畢竟有不少需求並不須要後端介入,單純改個前端版本後就要後端發佈一次,顯然是一件很是麻煩的事情。
這個須要專門的工具,用於配置版本發佈,我最近就在寫這個。
意義:
提升發佈效率,下降發佈帶來的人員時間損耗(這些都是錢),也能夠在前端版本回滾的時候,速度更快。
適用場景:有比較多獨立中小項目。好處:
能夠減小開發人員配置腳手架帶來的時間損耗(特殊功能能夠fork腳手架後再自行定製);
統一項目結構,方便管理,也下降項目交接時帶來的須要熟悉項目的時間;
方便統一技術棧,能夠預先引入固定的組件庫;
意義:
提升開發人員在多個項目之間的快速切換能力,提升項目可維護性,統一公司技術棧,避免由於環境不一樣致使奇怪的問題。
適用場景:須要SEO且前端使用React、vue,或前端介入後端邏輯,直接讀取後端服務或者數據庫的狀況。
SEO:仁者見仁智者見智,雖然不少公司已經不作了,但一般認爲,仍是有必定意義的(特別是須要搜索引擎引流的時候),所以React或者Vue的同構是必須的。而且同構還能夠下降首頁白屏時間;
前端讀取後端服務/數據庫:好處是提升前端的開發效率和對業務的支持能力,缺點是可能致使P0級故障。
意義:
讓前端能夠侵入後端領域,質的提高對業務的支持能力。
強烈推薦前端作本身的埋點系統。這個不一樣於後端的日誌系統。
前端埋點系統的好處:
記錄每一個頁面的訪問量(日周月年的UV、PV);
記錄每一個功能的使用量;
捕捉報錯狀況;
圖表化顯示,方便給其餘部門展現;
埋點系統是前端高度介入業務,把握業務發展狀況的一把利劍,經過這個系統,咱們能夠比後端更深入的把握用戶的習慣,以及給產品經理、運營等人員提供準確的數據依據。當有了數據後,前端人員就能夠針對性的優化功能、佈局、頁面交互邏輯、用戶使用流程。
埋點系統應和業務解耦,開發人員使用時註冊,而後在項目中引入。而後在埋點系統裏查看相關數據(例如以小時、日、周、月、年爲週期查看)
意義:
數據是money,數據是公司的生命線,數據是最好的武器。
監控和報警系統應基於埋點系統而創建,在如如下場景時[原創水印-做者:零零水(王冬),微信:qq20004604]觸發:
當訪問量有比較大的變化(好比日PV/UV只有以前20%如下)時,自動觸發報警,發送郵件到相關人員郵箱;
好比報錯量大幅度上升(好比200%或更高),則觸發報警;
當一段時間內沒有任何訪問量(不符合以前的狀況),則觸發報警;
每過一段時間,自動彙總訪問者/報錯觸發者的相關信息(例如系統、瀏覽器版本等);
建設這個系統的好處在於,提早發現一些不容易發現的bug(須要埋點作的比較紮實)。有一些線上bug,由於用戶環境特殊,致使沒法被開發人員和測試人員發現。但其中一部分bug又由於不涉及資金,並不會致使資損(所以也不會被後端的監控系統所發現),這樣的bug很是容易影響項目裏某個鏈路的正常使用。
意義:
提升項目的穩定性,提升對業務的把控能力。下降bug數,下降資損的可能性,提早發現某些功能的bug(在工單到來以前)。
前端的安全管理,一般要依賴於後端,至於只跟單純有關係的例如dom.innerHTML= 'xxx '這種太基礎,就不提了。
安全管理的很難從架構設計上徹底避免,但仍是有必定解決方案的,常見安全問題以下:
XSS注入:對用戶輸入的內容,須要轉碼(大部分時候要server端來處理,偶爾也須要前端處理),禁止使用eval函數;
https:這個顯然是必須的,好處很是多;
CSRF:要求server端加入CSRF的處理方法(至少在關鍵頁面加入);
意義:
減小安全漏洞,避免用戶受到損失,避免遭遇惡意攻擊,增長系統的穩定性和安全性。
Eslint的好處不少,強烈推薦使用:
下降低級bug(例如拼寫問題)出現的機率;
增長代碼的可維護性,可閱讀性;
硬性統一代碼風格,團隊協做起來時更輕鬆;
總的來講,eslint推薦直接配置到腳手架之中,對咱們提升代碼的可維護性的幫助會很大。能夠考慮在上傳到gitlab時,硬性要求eslint校驗,經過的才容許上傳。
意義:
提升代碼的可維護性,下降團隊協做的成本。
灰度發佈是大型項目在發佈時的常見方法,指在發佈版本時,初始狀況下,只容許小比例(好比1~5%比例的用戶使用),若出現問題時,能夠快速回滾使用老版本,適用於主鏈路和訪問量極大的頁面。
好處有如下幾點:
生產環境比開發環境複雜,灰度發佈時能夠在生產環境小範圍嘗試觀察新版本是否能夠正常運行,即便出問題,也能夠控制損失。
對於大版本更新,能夠先灰度一部分,觀察埋點效果和用戶反饋(即所謂的搶先試用版)。假如效果並很差,那麼回滾到老版本也能夠及時止損;
當咱們須要驗證某些想法或問題的時候,能夠先灰度一部分,快速驗證效果如何,而後查漏補缺或者針對性優化;
灰度發佈一般分爲多個階段:【1】1%;【2】5~10%;【3】30~50%;【4】全量推送(100%)。灰度發佈必定要容許配置某些IP/帳號訪問時,能夠直接訪問到灰度版本。
意義:
下降風險,提升發佈靈活度。
這個並非指常見的先後端分離,而是指在分配先後端管控的領域。
中小項目常見的狀況是後端只提供接口和讓某個url指向某個html,前端負責html、css、js等靜態資源。
但大型項目並不建議這麼作,建議前端負責除html之外的靜態資源,而html交給後端處理,理由有不少:
後端進行渲染,方便統一插入一些代碼和資源,例如埋點js,監控js,國際化文本資源,頁面標識符等。這些一般是後端經過調用某些服務直接寫入的;
當頁面須要統一的頭尾時(參考淘寶裏個人淘寶頁面),前端不該該關注這些跟當前頁面無關的東西;
某些東西,若是經過html來管理,那麼耦合度過高了,違背瞭解耦和分離的原則;
前端版本發佈在後端引入某種功能模塊後,能夠從單獨的頁面控制前端發佈內容,比更新html更方便,也利於灰度發佈;
意義:
更規範的進行頁面管理,下降頁面和功能的耦合度,減小複雜頁面的環境配置時間。
Mock也是常見前端系統之一,用於解決在後端接口未好時,生成返回的數據。
我我的不太建議開發一個專門的系統來Mock,更好的Mock手法是直接嵌入到腳手架之中。思路以下:
當在開發環境下,訪問連接一般是localhost:8000/index.html,此時加入後綴 ?debug=true;
封裝好的異步請求在發現當前連接有以上標誌時,認爲是測試環境,訪問/userinfo 時,不去讀取線上的數據(由於也讀取不到),去本地環境讀取 src/test_ajax/userinfo.json,並將內容返回給用戶;
異步請求正常拿到數據,在頁面中顯示
當線上接口能夠獲取到數據後,從network裏找到返回的數據,放入/ src/test_ajax/userinfo.json中,此時再次本地調試的話,至關於使用的是線上的真實數據。
複製代碼
這種處理,能夠下降mock的複雜度,隨時更改mock時返回的數據,比單獨開發一個mock系統性價比更高。
意義:
在先後端並行開發時,下降溝通交流成本,方便開發完畢後直接對接。
備份是常被忽略的一件事情,但當咱們碰見毀滅性場景時,缺乏備份帶來的損失是很是大的,常見場景:
服務器損壞,致使存在該服務器上的內容所有完蛋;
觸發某致命bug或者錯誤操做(例如rm -f),致使文件和數據所有消失;
數據庫出現錯誤操做或出現問題,致使用戶數據、公司資產遭受嚴重損失;
總的來講,沒人想碰見這樣的場景,但咱們必須考慮這種極端狀況的發生,所以須要從架構層面解決這個問題。常見方法是按期備份、多機備份、容災系統建設等。
意義:
避免在遭遇極端場景時,給公司帶來不可估量的損失。
除了特殊場景,一般推薦使用多頁架構。理由以下:
多頁項目,頁面和頁面之間是獨立的,不存在交互,所以當一個頁面須要單獨重構時,不會影響其餘頁面,對於有長期歷史的項目來講,可維護性、可重構性要高不少;
多頁項目的缺點是不一樣頁面切換時,會有一個白屏時間,但一般來講,這個時間並不長,大部分現有大公司的線上網頁,都是這樣的,所以認爲是能夠接受的;
多頁項目能夠單次只更新一個頁面的版本,而單頁項目若是其中一個功能模塊要更新(特別是公共組件更新),很容易讓全部頁面都須要更新版本;
多頁項目的版本控制更簡單,若是須要頁面拆分,調整部分頁面的使用流程,難度也會更低;
灰度發佈更友好;
以前面試的一家,採用了單頁的形式,以前由於種種緣由,同時採用了ng和react。因爲項目歷史也比較久(3年以上),結果致使目前繼續維護更新的難度很大,即便想部分重構,也很麻煩。
意義:
下降長期項目迭代維護的難度,
在項目比較大的時候,將全部頁面的前端文件放入到同一個代碼倉庫裏,我以前參與過一家企業的前端項目開發,發現其就是這麼作的。根據使用經驗來看[原創水印-做者:零零水(王冬),微信:qq20004604],存在不少問題:
會極大的增長代碼的維護難度;
項目會變得很醜陋;
不方便權限管理,容易形成頁面誤更改或代碼泄密;
任何人都有權利改任何他能看到的頁面(在合併代碼的時候,管理人員並不能肯定他本次修改的頁面是不是需求裏他應該改的頁面);
發佈成本高,即便改一個頁面,也須要發佈全部資源;
所以,咱們應該避免這種現象的發生,我的推薦以應用爲單位進行開發、發佈。所謂應用即指一個業務涉及到的先後端代碼,好處不少:
方便進行管理,當某個業務有需求變動時,能夠只給研發人員該業務前端應用的developer權限;
在須要發佈某業務時,只須要發佈該業務的所屬應用便可;
意義:
規範項目,增長代碼的安全性,下降項目維護成本。
這個蠻基礎的,對於組件庫的建設,不建議研發人員較少時去作這件事情,專職前端開發人數少於10人時,建議使用比較靠譜的第三方UI庫,例如Antd,這樣性價比更高。
設計基礎組件庫的前提,是要求統一技術棧,這樣才能最大化基礎組件庫的效益。組件庫建議以使用如下參考標準:
使用ts;
可擴展性強;
適用程度高;
文檔清楚詳細;
版本隔離,小版本優化加功能,大改須要大版本更新;
和UI協調統一,要求UI交互參與進來;
總的來講,建設起來後,利大於弊,可是須要專人維護,所以仍是有必定成本的。
意義:
統一不一樣/相同產品線之間的風格,給用戶更好的體驗,減小單次開發中寫UI組件時浪費的時間和人力,提升開發效率。
前端有三大主流框架,還有兼容性最強jQuery,以及各類第三方庫,UI框架。所以項目需求若是複雜一些,很容易造成一個大雜燴。所以前端的技術棧必須統一,具體來講,建議實現如下舉措:
三大框架選型其一,團隊水平通常推薦Vue、水平較好推薦React,對外項目選React或者ng;
須要兼容IE8或更老版本時,建議使用jQuery;
組件庫自建或者統一選擇一個固定的第三方;
一些特殊第三方庫統一使用一個版本,例如須要使用地圖時,固定使用高德或百度或騰訊地圖;
基礎設施建設應避免重複造輪子,全部團隊儘可能共用,並有專門的前端平_臺負責統一這些東西,對於特殊需求,能夠新建,但應當有說服力;
總的來講,技術棧統一的好處不少,能夠有效提升開發效率,下降重複造輪子產生的成本。
意義:
方便招人,簡化團隊成員培養成本,以及提升項目的可持續性。
常見的問題是IE六、七、8,以及部分小衆瀏覽器(PC和手機)產生的奇怪問題。所以應該考慮統一解決方案,避免bug的重複產生。常看法決方案有:
配置postcss,讓某些css增長兼容性前綴;
寫一個wepback的loader,處理某些特殊場景;
規範團隊代碼,使用更穩定的寫法(例如移動端避免使用fixed進行佈局);
對常見問題、疑難問題,總結解決方案並團隊共享;
建議或引導用戶使用高版本瀏覽器(好比chrome);
意義:
避免瀏覽器環境產生的bug,以及排查此類bug所浪費的大量時間。
爲了提升公司內部的溝通效率,總結經驗,以及保密緣由。應建設一個內部論壇+博客站點。其具有的好處以下:
能夠記錄公司的歷史;
研發同窗之間分享經驗;
總結轉載一些外界比較精品的文章,提升你們的眼界;
增長公司內部同窗的交流,有利於公司的團隊和文化建設;
對某些技術問題能夠進行討論,減小因沒有達成共識帶來的溝通損耗;
衆所周知,大型互聯網公司一般都有這樣一個內部論壇和博客站點。其下降了公司的溝通和交流成本,也增長了公司的技術積累。
意義:
博客加強技術積累,論壇加強公司內部溝通能力。
當公司內部人員較多時,應有一個專門的平臺,來管理、規範用戶的權限以及可訪問內容[原創水印-做者:零零水(王冬),微信:qq20004604]。權限管理平臺有幾個特色:
必然和Server端自然高耦合度,所以須要有專門的控制模塊負責處理權限問題(負責Server端開發處理,或者前端經過中間層例如Node層介入處理);
自動化流程控制,即用戶建立、申請、審批、離職自動刪除,都應該是由系統推動並提醒相關人士,必要時應能觸發報警;
權限應有時效性,減小永久性權限的產生;
審批流程應清晰可見,每一階段流程應具體明確;
應與公司流程緊密結合,而且提升可修改性,方便公司後期進行流程優化;
意義:
使得公司內部流程正規化、信息化。
當公司內部業務線比較複雜但相互之間的耦合度比較高時,咱們應該考慮設計添加單點登陸系統。具體來講,用戶在一處登陸,便可以在任何頁面訪問,登出時,也一樣在任何頁面都失去登陸狀態。SSO的好處不少:
加強用戶體驗;
打通了不一樣業務系統之間的用戶數據;
方便統一管理用戶;
有利於引流;
下降開發系統的成本(不須要每一個業務都開發一次登陸系統和用戶狀態控制);
總的來講,大中型web應用,SSO能夠帶來不少好處,缺點卻不多。
意義:
用戶體驗加強,打通不一樣業務之間的間隔,下降開發成本和用戶管理成本。
前端資源的加載速度是衡量用戶體驗的重要指標之一。而現實中,由於種種因素,用戶在加載頁面資源時,會受到不少限制。所以上CDN是很是有意義的,好處以下:
用戶來自不一樣地區,加入CDN可使用戶訪問資源時,訪問離本身比較近的CDN服務器,下降訪問延遲;
下降服務器帶寬使用成本;
支持視頻、靜態資源、大文件、小文件、直播等多種業務場景;
消除跨運營商形成的網絡速度較慢的問題;
下降DDOS攻擊形成的對網站的影響;
CDN是一種比較成熟的技術,各大雲平_臺都有提供CDN服務,價格也不貴,所以CDN的性價比很高。
意義:
增長用戶訪問速度,下降網絡延遲,帶寬優化,減小服務器負載,加強對攻擊的抵抗能力。
目前來看,負載均衡一般使用Nginx比較多,之前也有使用Apache。當碰見大型項目的時候,負載均衡和分佈式幾乎是必須的。負載均衡有如下好處:
下降單臺server的壓力,提升業務承載能力;
方便應對峯值流量,擴容方便(如舉辦某些活動時);
加強業務的可用性、擴展性、穩定性;
負載均衡已是蠻常見的技術了,好處不用多說,很容易理解。
意義:
加強業務的可用性、擴展性、穩定性,能夠支持更多用戶的訪問。
目前常見場景是一個業務,同時有PC頁面和H5頁面,因爲業務是同樣的,所以應避免同一個業務有多套接口分別適用於PC和H5端。所以解決方案以下:
後端提供的接口,應該同時包含PC和H5的數據(即單獨對一個存在亢餘數據);
接口應當穩定,即當業務變動時,應儘可能採起追加數據的形式;
只有在單獨一端須要特殊業務流程時,設計單端獨有接口;
多端共用接口,是減小開發工做量,而且提升業務可維護性的重要解決方案。
意義:
下降開發工做量,加強可維護性