淺談大型項(xiàng)目中前端管理架構(gòu)
今天來(lái)跟大家聊聊大型組織中(前端工程師的人數(shù)開(kāi)始超過(guò)15人)前端管理架構(gòu),主要涉及的是團(tuán)隊(duì)協(xié)作。
本文不討論在這樣的大公司中常見(jiàn)的管理問(wèn)題或業(yè)務(wù)領(lǐng)域問(wèn)題,而是關(guān)注前端的協(xié)作架構(gòu)。
如今,前端架構(gòu)涉及的領(lǐng)域太多,因此,建議將其分為以下幾部分:

一、Visual Code
從最簡(jiǎn)單的主題開(kāi)始,這是前端開(kāi)發(fā)最常用的代碼編輯器。
最可能是因?yàn)槲覀兿M谕患夜鹃_(kāi)發(fā)多個(gè)前端應(yīng)用程序,所以我們希望它們具有:
- 品牌認(rèn)知度
- 相同的
UI/UX
為此,需要一個(gè)設(shè)計(jì)系統(tǒng)。設(shè)計(jì)團(tuán)隊(duì)必須提出設(shè)計(jì)規(guī)范,并在所有將來(lái)的產(chǎn)品設(shè)計(jì)中遵循這些設(shè)計(jì)準(zhǔn)則。即使這已經(jīng)是一個(gè)非常復(fù)雜的任務(wù),并且需要設(shè)計(jì)團(tuán)隊(duì)、工程師和產(chǎn)品之間進(jìn)行大量討論和協(xié)調(diào)。
從前端的角度來(lái)看,需要提供一種工具來(lái)在工程師之間實(shí)施和共享此設(shè)計(jì)規(guī)范。為此,一個(gè)好的解決方案是創(chuàng)建npm軟件包,該軟件包將由Storybook或其他類似工具直觀地呈現(xiàn)。我認(rèn)為,擁有專用的Web資源(帶有URL)以及有關(guān)如何使用此軟件包的文檔非常重要。該Web資源將由前端工程師和設(shè)計(jì)師使用,并且可以作為他們之間對(duì)話的重要參考。

小結(jié):在這一點(diǎn)上,有一個(gè)設(shè)計(jì)規(guī)范及其在包中的封裝和它的交互式文檔。所有的前端應(yīng)用程序中共享并采用這個(gè)
package。
二、代碼結(jié)構(gòu)
接下來(lái)談?wù)勅粘>幋a,我們確實(shí)實(shí)現(xiàn)了新功能、修復(fù)了bug,如果需要的話重構(gòu)代碼。我們需要關(guān)注我們的代碼庫(kù),試圖讓它變得友好和容易理解。但是,當(dāng)我們的公司開(kāi)始有不是1個(gè)、也不是2個(gè),而是幾十個(gè)大小項(xiàng)目時(shí),會(huì)發(fā)生什么呢?
通常,人們圍繞一些項(xiàng)目分組,并開(kāi)始只與這組項(xiàng)目一起工作。由于人的本性和有限的時(shí)間,我們通常不能在一段時(shí)間內(nèi)兼顧多于2-5個(gè)項(xiàng)目。所以很自然地,我們開(kāi)始受到這些群體的影響。順便說(shuō)一句,感謝美國(guó)國(guó)家航空航天局(NASA)為我們提供了這么棒的照片。

但是,我們開(kāi)始遇到越來(lái)越多的情況,當(dāng)人們進(jìn)行跨團(tuán)隊(duì)協(xié)作時(shí),需要檢查彼此的代碼和解決方案,甚至在其他應(yīng)用程序中也要修復(fù)一些錯(cuò)誤,或者在某個(gè)外部應(yīng)用程序(對(duì)于他們的小組來(lái)說(shuō)是外部的)中添加他們需要的東西。影響力)。壞消息是,這一過(guò)程正在幾乎不受控制的大公司中發(fā)生。好消息-我們可以幫助改善它。
怎么樣?正確。通過(guò)為公司中的所有項(xiàng)目提供相同的代碼結(jié)構(gòu),編碼和結(jié)構(gòu)準(zhǔn)則。
讓我們更深入地了解代碼結(jié)構(gòu)的含義:
-
項(xiàng)目中的文件夾結(jié)構(gòu)
工程師第一次進(jìn)入新項(xiàng)目時(shí)-與項(xiàng)目中的文件夾結(jié)構(gòu)相同,他們知道所有內(nèi)容都對(duì)導(dǎo)航和搜索有很大幫助。
-
配置或支持性文件的
文件,如package.json、.gitignore、.editorconfig、webpack.config等他們應(yīng)該總是在同一個(gè)地方,在每一個(gè)項(xiàng)目。如果需要,將它們連接到測(cè)試配置文件或CI文件。
-
文件類型的固定位置
如果相同文件類型的位置始終遵循相同的結(jié)構(gòu),則效果也很好。例如,如果組件文件夾中始終有一個(gè)
style.css文件:/Component --/Component.tsx --/style.css --/index.ts -
組件內(nèi)部結(jié)構(gòu):文件內(nèi)部的結(jié)構(gòu)應(yīng)相同:導(dǎo)入、導(dǎo)出的順序、公共功能的位置、類型等。在每種類型的文件中,都應(yīng)該知道期望的內(nèi)容。
-
命名規(guī)范:這包括文件夾、文件、變量、函數(shù)、類、類型等的名稱
-
編碼約定:總的來(lái)說(shuō),編碼約定是一個(gè)非常寬泛的部分,但是在這里我只想包含不適合其余部分的內(nèi)容
在實(shí)踐中,相同的代碼結(jié)構(gòu)和項(xiàng)目工具集非常緊密地結(jié)合在一起,有利于開(kāi)發(fā)效率。我所說(shuō)的工具集是指CLI工具(項(xiàng)目啟動(dòng)、檢測(cè)、測(cè)試等)、IDE擴(kuò)展等等。我們將在下一節(jié)中討論工具集主題。

小結(jié):在應(yīng)用了本節(jié)并采用它之后,我們應(yīng)該使組織中的所有項(xiàng)目都具有相同的文件夾結(jié)構(gòu)、命名規(guī)范、文件結(jié)構(gòu)等。理想情況下,每個(gè)開(kāi)發(fā)人員都可以在項(xiàng)目之間無(wú)縫切換,不需要花額外的時(shí)間來(lái)學(xué)習(xí)和理解代碼。
三、技術(shù)棧
與上一節(jié)類似,我們確實(shí)希望在組織的各個(gè)項(xiàng)目中擁有統(tǒng)一的技術(shù)棧。
在Frontend項(xiàng)目中,技術(shù)堆棧的組件可以是:構(gòu)建該項(xiàng)目所基于的框架、主要語(yǔ)言、樣式處理器、數(shù)據(jù)層(例如Apollo)、狀態(tài)管理、測(cè)試、代碼整理、構(gòu)建系統(tǒng)等。
當(dāng)然,所有規(guī)則中都有例外。在本主題中,我也想說(shuō)一句,有時(shí)某些技術(shù)非常適合某些特定項(xiàng)目,即使這些技術(shù)不屬于全球公司范圍的技術(shù)堆棧。但是,每當(dāng)這種想法脫離公司技術(shù)堆棧時(shí),都應(yīng)該三思而后行,因?yàn)橹С执祟愂聞?wù)的成本非常高,需要收益必須非常可觀來(lái)支撐。
讓我們?cè)谶@里提及一些通用技術(shù)堆棧,該堆棧現(xiàn)在可以適合大多數(shù)項(xiàng)目(當(dāng)然,它僅涵蓋實(shí)際技術(shù)堆棧的一部分,但對(duì)于某人來(lái)說(shuō)可能是一個(gè)很好的起點(diǎn)):
在我們?yōu)楣径x技術(shù)棧并達(dá)成共識(shí)之后,還有其他非常重要的成功支柱。
首先,我們需要寫(xiě)下來(lái)的技術(shù)堆棧的文件。這些文檔應(yīng)該在工程師之間方便且容易地共享,因此他們始終可以相互鏈接并維護(hù)。
其次,我們應(yīng)該再次使用已定義的技術(shù)堆棧來(lái)寫(xiě)下并共享文檔,以及如何啟動(dòng)和引導(dǎo)新項(xiàng)目的方式。

四、工具
這個(gè)話題很重要。現(xiàn)在,我們幾乎在所有地方都使用了一些其他工具:整理、構(gòu)建應(yīng)用程序、CI、組件生成器等等。因此,這就是為什么能確定我們是否可以為項(xiàng)目選擇正確的工具的原因至關(guān)重要。好的工具還是不好的工具(或者根本沒(méi)有工具),就像自動(dòng)化測(cè)試與手動(dòng)測(cè)試之間的比較一樣。
我們之前在前幾節(jié)中談到了技術(shù)堆棧和代碼結(jié)構(gòu),并提到我們需要編寫(xiě)大量文檔來(lái)使項(xiàng)目成員關(guān)注它們。但是正確的工具集可以有機(jī)會(huì)按照公司的準(zhǔn)則進(jìn)行自動(dòng)化。
例如,如果具有指定的編碼風(fēng)格,則可以為項(xiàng)目提供linting工具集,該工具集默認(rèn)情況下遵循這些規(guī)則。如果具有定義的技術(shù)堆棧,那么良好的CLI工具將提供機(jī)會(huì),使用技術(shù)堆棧中的特定技術(shù)來(lái)引導(dǎo)新項(xiàng)目。
讓我們嘗試討論工具可以覆蓋前端體系結(jié)構(gòu)的哪些部分:
-
代碼風(fēng)格和結(jié)構(gòu):如我們之前所討論的,可以通過(guò)工具輕松實(shí)現(xiàn)自動(dòng)化
-
項(xiàng)目自舉:無(wú)需提出新的項(xiàng)目結(jié)構(gòu),手動(dòng)安裝所有需要的軟件包等。
-
組件生成:大多數(shù)情況下,應(yīng)用程序中的某些組件甚至都不包含單個(gè)文件,因此文件創(chuàng)建、鏈接或者導(dǎo)入它們會(huì)花費(fèi)一些時(shí)間,因此需要自動(dòng)化。
-
啟動(dòng)和構(gòu)建:當(dāng)然,最顯而易見(jiàn)的要自動(dòng)化的事情是如何構(gòu)建或啟動(dòng)應(yīng)用程序。
-
測(cè)試:為測(cè)試構(gòu)建應(yīng)用程序并實(shí)際運(yùn)行所有類型的測(cè)試(單元、集成等)的過(guò)程。
-
依賴關(guān)系管理:現(xiàn)在大約80%的代碼之間是有依賴關(guān)系。因此,需要讓他們保持最新版本,并且要在大型公司中進(jìn)行管理并非易事。
-
跨項(xiàng)目的依賴關(guān)系:很可能我們的項(xiàng)目不是孤立地工作,可能依賴于其他項(xiàng)目,,因此我們可能需要一些工具來(lái)簡(jiǎn)化鏈接它們的過(guò)程,并結(jié)合多個(gè)項(xiàng)目(例如Bit等),等等。
-
CI:CI是我們?nèi)粘9ぞ呒闹匾M成部分,自動(dòng)化和統(tǒng)一對(duì)您的組織可能是一項(xiàng)非常有益的工作。
如果不想開(kāi)發(fā)自己的新工具集,我可以推薦NX工具集,它是最有趣的候選對(duì)象之一。同樣,Babel的創(chuàng)建者似乎也執(zhí)行了類似的解決方案,可能需要check out — Rome。這些工具并不能涵蓋所有內(nèi)容,而是我們所討論內(nèi)容的很大一部分,因此可以作為一個(gè)很好的起點(diǎn)。

小結(jié):試想一下,在我們完成所有部分的采用之后,我們的體系結(jié)構(gòu)將變得多么偉大。
每個(gè)項(xiàng)目都是相同的,并由統(tǒng)一工具集維護(hù)和管理。每個(gè)項(xiàng)目都可以以相同的方式啟動(dòng)和構(gòu)建。新的組件在相同的位置使用相同的命名準(zhǔn)則生成。
五、部署
通常,在前端體系結(jié)構(gòu)的這一部分中,工程師最不用擔(dān)心。也許是因?yàn)樗诖蠖鄶?shù)時(shí)候都與編碼本身無(wú)關(guān),而且可能并不那么令人興奮,但同樣重要。
在生產(chǎn)中,我們通常需要注意以下事項(xiàng):
-
Google Analytics(分析):各種不同的跟蹤事件,例如Google Analytics(分析),Segment,HotJar等。
-
狀態(tài)監(jiān)視:這包括諸如運(yùn)行狀況檢查之類的內(nèi)容,甚至可以在生產(chǎn)中運(yùn)行測(cè)試,錯(cuò)誤報(bào)告(例如Sentry)等。
*** 性能**:這與上一項(xiàng)相似,但更注重性能。這包括測(cè)量響應(yīng)時(shí)間,第一個(gè)有意義的油漆等。(可能是工具#1- Lighthouse)
-
A/B測(cè)試:各種A/B測(cè)試解決方案或功能標(biāo)記。
-
緩存:諸如Varnish和Cloudflare之類的工具。
所有這些都可以在公司的前端應(yīng)用程序中統(tǒng)一,這將簡(jiǎn)化工程師的工作。例如,通過(guò)添加具有預(yù)定義的初始配置的軟件包,并將這些軟件包添加到自舉項(xiàng)目中。
生產(chǎn)的另一部分是代碼準(zhǔn)備,例如:
-
縮小:只是代碼縮小
-
源映射:某些其他工具,例如Sentry,可能也需要源映射。
-
資產(chǎn)準(zhǔn)備:為具有不同分辨率的屏幕,裁切圖像等做準(zhǔn)備。
這些都是將要添加到我們用于管理前端應(yīng)用程序的工具集中的不錯(cuò)的選擇,我們?cè)?ldquo;工具”部分中已經(jīng)討論過(guò)。

六、開(kāi)發(fā)
CLI工具
當(dāng)我們接觸前端CLI工具時(shí),已經(jīng)部分地在“工具”部分討論了開(kāi)發(fā)經(jīng)驗(yàn)。統(tǒng)一工具是工程師日常工作的重要組成部分,但不是全部。
API
在本地使用舒適的API是我們改善開(kāi)發(fā)人員體驗(yàn)和開(kāi)發(fā)速度的第二件事。通常,為前端工程師在本地提供API并不是一件容易的事:這可能包括他們不熟悉的安裝工具或框架。即使通過(guò)泊塢設(shè)置進(jìn)行安裝,這也可能會(huì)占用開(kāi)發(fā)人員計(jì)算機(jī)的大量計(jì)算資源(如果不是,則可以將其視為安裝)。在這種情況下,什么是解決方案-外部服務(wù)的API。對(duì)于所有工程師來(lái)說(shuō),這可以是一臺(tái)服務(wù)器,也可以是某種機(jī)制來(lái)輕松引導(dǎo)您自己的專用服務(wù)器進(jìn)行開(kāi)發(fā)。
CI
CI是第三大部分。我可能認(rèn)為,您的公司已經(jīng)選擇了一些CI工具作為前端并使用了該工具 (例如Circle CI,Concourse CI或任何其他工具)。如果不是,則應(yīng)統(tǒng)一。
我認(rèn)為,特定項(xiàng)目的CI配置應(yīng)該是該項(xiàng)目團(tuán)隊(duì)的一部分。這給CI帶來(lái)了穩(wěn)定的機(jī)會(huì),因?yàn)橛行┤藢?duì)CI感興趣,每天都要使用它,并且具有修復(fù),配置和改進(jìn)它的能力和技能。
但是,并非所有工作都應(yīng)由團(tuán)隊(duì)完成。對(duì)于前端應(yīng)用程序,存在相當(dāng)特定的一堆作業(yè),這可能是需要的。特別是,如果我們能夠設(shè)法統(tǒng)一文件夾/代碼結(jié)構(gòu),技術(shù)堆棧等。那么在您的公司工作一段時(shí)間后,也許可以在您的CI工具階段檢測(cè)到這些模式,將這些階段實(shí)現(xiàn)為某種“構(gòu)建基塊”,并為您的工程師提供了一個(gè)機(jī)會(huì),就是從這些統(tǒng)一的“構(gòu)建基塊”構(gòu)建其CI管道。
演示環(huán)境
最后是最后-驗(yàn)證實(shí)現(xiàn)的功能。在工程師完成所有工作并實(shí)施之后,幾乎總是需要某種方式來(lái)檢查其外觀和工作方式,并將其與其他工程師,設(shè)計(jì)師或其他利益相關(guān)者共享。對(duì)于此類需求,它可以通過(guò)提供的URL在特定PR的應(yīng)用程序的臨時(shí)部署版本中發(fā)揮出色的作用。
該解決方案大大加快了不同團(tuán)隊(duì)與人員之間的溝通,我認(rèn)為這是必須具備的。但是,此臨時(shí)部署的版本應(yīng)盡可能接近生產(chǎn)環(huán)境,因?yàn)樗彩菣z查某些表面錯(cuò)誤或錯(cuò)誤的好工具。
如果前端應(yīng)用程序構(gòu)建和部署流程管道是統(tǒng)一的,則可以輕松地將其添加到項(xiàng)目中并自動(dòng)進(jìn)行。同樣,諸如Kubernetes和Helm之類的此類工具或類似工具也可以在實(shí)現(xiàn)中提供很大幫助。

小結(jié):借助具有集成塊的單個(gè)CI工具,使用統(tǒng)一的CLI前端工具和演示環(huán)境,即可輕松高效地進(jìn)行開(kāi)發(fā)流程。所有這些應(yīng)使我們的開(kāi)發(fā)過(guò)程盡可能順利。
7、模塊化
這個(gè)話題非常大,可能需要一篇單獨(dú)的文章來(lái)討論,但我會(huì)試著簡(jiǎn)要地介紹一下。
在大型組織中,龐大的代碼庫(kù)并不罕見(jiàn)。與所有已知的問(wèn)題一起出現(xiàn),如緩慢的CI管道、協(xié)作工作問(wèn)題、緩慢的測(cè)試等。因此,前端架構(gòu)的一個(gè)重要部分是決定我們希望看到獨(dú)立前端應(yīng)用/模塊的粒度。
我們現(xiàn)在有三種主要的模式:
-
Monolith:一個(gè)大的存儲(chǔ)庫(kù)包含一個(gè)項(xiàng)目和所有的代碼,所有的團(tuán)隊(duì)同時(shí)在這個(gè)存儲(chǔ)庫(kù)中工作。
-
Monorepo:很多項(xiàng)目,但仍然有一個(gè)很大的存儲(chǔ)庫(kù)(在wiki中是monorepo)。所有的團(tuán)隊(duì)仍然使用相同的存儲(chǔ)庫(kù),但是使用的是不同的項(xiàng)目。我們已經(jīng)有機(jī)會(huì)修復(fù)一些問(wèn)題了,我們采用的是單一的方法,只針對(duì)特定的項(xiàng)目運(yùn)行管道,項(xiàng)目有更小的測(cè)試套件等等。如果你選擇了這種方法,像Lerna這樣的工具可以讓你的生活更簡(jiǎn)單。
-
Repo per project:每個(gè)項(xiàng)目都有自己的存儲(chǔ)庫(kù)和所有支持的東西,比如CI管道、部署等。
在所有這些模型中,項(xiàng)目可能意味著獨(dú)立的前端應(yīng)用程序、頁(yè)面、獨(dú)立的前端模塊等等。這取決于您希望如何劃分前端應(yīng)用程序的粒度。在大多數(shù)情況下,這種劃分應(yīng)該與所需的組織結(jié)構(gòu)和人員管理同步。
決定如何分割應(yīng)用程序后的第二大主題是如何將這些部分連接在一起(如果你決定分割應(yīng)用程序)。
這里我們有以下方法:
Build-time composition:項(xiàng)目可以只是npm軟件包,可以在構(gòu)建期間安裝和組成。Server-side composition:通常包括服務(wù)器端渲染和服務(wù)器上發(fā)生的合成。像Hypernova這樣的工具可以幫助更好地組織它。Client-side composition:瀏覽器內(nèi)部項(xiàng)目的組成。非常重要的是要提到Module Federation,這是Webpack 5中引入的一種新方法。Route composition:超級(jí)簡(jiǎn)單——每個(gè)項(xiàng)目都有自己的URL,在Nginx層級(jí)上我們決定把用戶重定向到哪里。
就像我之前說(shuō)的,用這么小的格式來(lái)涵蓋這個(gè)主題是非常困難的,但我希望你至少能找到一些自己感興趣的想法,并自己深入研究這個(gè)主題。
小結(jié):我們找到了一種方法,通過(guò)組織存儲(chǔ)庫(kù),將我們的項(xiàng)目分成更小的部分(最有可能),通過(guò)使團(tuán)隊(duì)更獨(dú)立于彼此,使我們的團(tuán)隊(duì)快樂(lè)和富有成效。
八、測(cè)試
關(guān)于前端應(yīng)用程序的測(cè)試,有很多可用的資源,所以我盡量不深入細(xì)節(jié),而是更多地關(guān)注大型組織的問(wèn)題以及我們?nèi)绾谓鉀Q它們。
第一步——每個(gè)工程師對(duì)測(cè)試技術(shù)的理解是不同的,以及在什么情況下應(yīng)用哪種技術(shù),如何編寫(xiě)“好的”測(cè)試,等等。所以非常有必要記錄下公司所使用的測(cè)試水平的所有細(xì)微差別和指導(dǎo)方針,以及每個(gè)標(biāo)準(zhǔn)的指導(dǎo)方針。
你的測(cè)試策略中可能需要的測(cè)試級(jí)別:
- 單元測(cè)試
- 整體測(cè)試
- 端到端測(cè)試
- 其他的
此外,第二步,我們需要在公司的不同前端應(yīng)用程序中統(tǒng)一它們,因此人們?cè)谶w移到其他項(xiàng)目時(shí)不會(huì)對(duì)如何以及如何進(jìn)行測(cè)試有任何疑問(wèn)。
如果設(shè)法統(tǒng)一了測(cè)試級(jí)別和方法,就可以自動(dòng)幫助解決第二個(gè)問(wèn)題——測(cè)試基礎(chǔ)設(shè)施設(shè)置。每個(gè)項(xiàng)目都需要在本地和CI上設(shè)置和配置一些測(cè)試基礎(chǔ)設(shè)施。例如,我們決定使用Cypress,它需要在docker鏡像中運(yùn)行。這需要一些時(shí)間在本地和CI上進(jìn)行設(shè)置。如果我們把這個(gè)數(shù)字乘以我們所擁有的項(xiàng)目數(shù)量,那將是非常巨大的時(shí)間。因此,解決方案——再次統(tǒng)一并為項(xiàng)目提供一些工具。聽(tīng)起來(lái)很簡(jiǎn)單,但卻需要大量的時(shí)間去實(shí)現(xiàn)。