真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

軟件架構(gòu)之如何理解前后端分離與前端模塊化

這篇文章主要講解了“軟件架構(gòu)之如何理解前后端分離與前端模塊化”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“軟件架構(gòu)之如何理解前后端分離與前端模塊化”吧!

創(chuàng)新互聯(lián)建站是一家專注于成都做網(wǎng)站、網(wǎng)站制作與策劃設(shè)計(jì),張掖網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:張掖等地區(qū)。張掖做網(wǎng)站價(jià)格咨詢:13518219792

前后端分離架構(gòu)

在正式說明前后臺架構(gòu)分離之前,我們來看一下多年之前,傳統(tǒng)軟件開發(fā)的架構(gòu)模式。

為什么要前后端分離

還記得零幾年我上大學(xué)的時(shí)候,在初學(xué) Java Web 開發(fā)時(shí),課本上介紹的還是 JSP + Servlet  這種很傳統(tǒng)的架構(gòu)模式,這時(shí)候前端和后端業(yè)務(wù)邏輯代碼都在一個(gè)工程里面,還沒有分離開來,這種開發(fā)模式屬于 Model1  模式,雖然實(shí)現(xiàn)了邏輯功能和顯示功能的分離,但是由于視圖層和控制層都是由 JSP 頁面實(shí)現(xiàn)的,即視圖層和控制層并沒有實(shí)現(xiàn)分離。

隨著學(xué)習(xí)的深入以及漸漸流行的企業(yè)應(yīng)用開發(fā),我們漸漸的擯棄這種技術(shù)選型,并開始在項(xiàng)目中使用了若干開源框架,常用的框架組合有 Spring  +Struts/Spring MVC + Hibernate/Mybatis  等等,由于框架的優(yōu)越性以及良好的封裝性使得這套開發(fā)框架組合迅速成為各個(gè)企業(yè)開發(fā)中的不二之選,這些框架的出現(xiàn)也減少了開發(fā)者的重復(fù)編碼工作,簡化開發(fā),加快開發(fā)進(jìn)度,降低維護(hù)難度,隨之而火熱的是這套技術(shù)框架背后的開發(fā)模式,即  MVC 開發(fā)模式,它是為了克服 Model1 存在的不足而設(shè)計(jì)的。

MVC 的具體含義是:Model + View + Controller,即模型+視圖+控制器,

  • Model 模型層: 它常常使用 JavaBean  來編寫,它接受視圖層請求的數(shù)據(jù),然后進(jìn)行相應(yīng)的業(yè)務(wù)處理并返回最終的處理結(jié)果,它負(fù)擔(dān)的責(zé)任最為核心,并利用 JavaBean  具有的特性實(shí)現(xiàn)了代碼的重用和擴(kuò)展以及給維護(hù)帶來了方便。

  • View 視圖層: 代表和用戶交互的界面,負(fù)責(zé)數(shù)據(jù)的采集和展示,通常由 JSP 實(shí)現(xiàn)。

  • Controller 控制層:  控制層是從用戶端接收請求,然后將請求傳遞給模型層并告訴模型層應(yīng)該調(diào)用什么功能模塊來處理該請求,它將協(xié)調(diào)視圖層和模型層之間的工作,起到中間樞紐的作用,它一般交由  Servlet 來實(shí)現(xiàn)。

MVC的工作流程如下圖所示。

軟件架構(gòu)之如何理解前后端分離與前端模塊化

同時(shí),項(xiàng)目開發(fā)在進(jìn)行模塊分層時(shí)也會劃分為三層:控制層,業(yè)務(wù)層,持久層??刂茖迂?fù)責(zé)接收參數(shù),調(diào)用相關(guān)業(yè)務(wù)層,封裝數(shù)據(jù),以及路由并將數(shù)據(jù)渲染到 JSP  頁面,然后在 JSP  頁面中將后臺的數(shù)據(jù)展現(xiàn)出來,相信大家對這種開發(fā)模式都十分熟悉,不管是企業(yè)開發(fā)或者是個(gè)人項(xiàng)目的搭建,這種開發(fā)模式都是大家的首選,不過,隨著開發(fā)團(tuán)隊(duì)的擴(kuò)大和項(xiàng)目架構(gòu)的不斷演進(jìn),這套開發(fā)模式漸漸有些力不從心。

接下來,我們來分析下這套開發(fā)模式的痛點(diǎn)。

痛點(diǎn)一:JSP 效率問題

首先,JSP 必須要在 Servlet 容器中運(yùn)行(例如 Tomcat,jetty 等),在請求 JSP 時(shí)也需要進(jìn)行一次編譯過程,最后被譯成 Java  類和 class 文件,這些都會占用 PermGen 空間,同時(shí)也需要一個(gè)新的類加載器加載,JSP 技術(shù)與 Java 語言和 Servlet  有強(qiáng)關(guān)聯(lián),在解耦上無法與模板引擎或者純 html 頁面相媲美。其次每次請求 JSP 后得到的響應(yīng)都是 Servlet 通過輸出流輸出的 html  頁面,效率上也沒有直接使用 html 高。由于 JSP 與 Servlet 容器的強(qiáng)關(guān)聯(lián),在項(xiàng)目優(yōu)化時(shí)也無法直接使用 Nginx 作為 JSP 的 web  服務(wù)器,性能提升不高。

痛點(diǎn)二:人員分工不明

在這種開發(fā)模式下的工作流程通常是:設(shè)計(jì)人員給出頁面原型設(shè)計(jì)后,前端工程師只負(fù)責(zé)將設(shè)計(jì)圖切成 html 頁面,之后則需要由后端開發(fā)工程師來將 html 轉(zhuǎn)為  JSP  頁面進(jìn)行邏輯處理和數(shù)據(jù)展示。在這種工作模式下,人為出錯(cuò)率較高,后端開發(fā)人員任務(wù)更重,修改問題時(shí)需要雙方協(xié)同開發(fā),效率低下,一旦出現(xiàn)問題后,前端開發(fā)人員面對的是充滿標(biāo)簽和表達(dá)式的  JSP 頁面,后端人員在面對樣式或者交互的問題時(shí)本就造詣不高的前端技術(shù)也會捉襟見肘。

在某些緊急情況下也會出現(xiàn)前端人員調(diào)試后端代碼,后端開發(fā)人員調(diào)試前端代碼這些讓人捧腹的現(xiàn)象,分工不明確,且溝通成本大,一旦某些功能需要返工則需要前后端開發(fā)人員,這種情況下,對于前后端人員的后期技術(shù)成長也不利,后端追求的是高并發(fā)、高可用、高性能、安全、架構(gòu)優(yōu)化等,前端追求的是模塊化、組件整合、速度流暢、兼容性、用戶體驗(yàn)等等,但是在  MVC 這種開發(fā)模式下顯然會對這些技術(shù)人員都有一定的掣肘。

痛點(diǎn)三:不利于項(xiàng)目迭代

項(xiàng)目初期,為了快速上線應(yīng)用,選擇使用這種開發(fā)模式來進(jìn)行 Java Web  項(xiàng)目的開發(fā)是非常正確的選擇,此時(shí)流量不大,用戶量也不高,并不會有非??量痰男阅芤螅请S著項(xiàng)目的不斷成長,用戶量和請求壓力也會不斷擴(kuò)大,對于互聯(lián)網(wǎng)項(xiàng)目的性能要求是越來越高,如果此時(shí)的前后端模塊依舊耦合在一起是非常不利于后續(xù)擴(kuò)展的。舉例說明一下,為了提高負(fù)載能力,我們會選擇做集群來分擔(dān)單個(gè)應(yīng)用的壓力,但是模塊的耦合會使得性能的優(yōu)化空間越來越低,因?yàn)閱蝹€(gè)項(xiàng)目會越來越大,不進(jìn)行合理的拆分無法做到最好的優(yōu)化,又或者在發(fā)版部署上線的時(shí)候,明明只改了后端的代碼,前端也需要重新發(fā)布,或者明明只改了部分頁面或者部分樣式,后端代碼也需要一起發(fā)布上線,這些都是耦合較嚴(yán)重時(shí)常見的不良現(xiàn)象,因此原始的前后端耦合在一起的架構(gòu)模式已經(jīng)逐漸不能滿足項(xiàng)目的演進(jìn)方向,需要需找一種解耦的方式替代當(dāng)前的開發(fā)模式。

痛點(diǎn)四:不滿足業(yè)務(wù)需求

隨著公司業(yè)務(wù)的不斷發(fā)展,僅僅只有瀏覽器端的 Web 應(yīng)用已經(jīng)逐漸顯得有些不夠用了,目前又是移動互聯(lián)網(wǎng)急劇增長的時(shí)代,手機(jī)端的原生 App  應(yīng)用已經(jīng)非常成熟,隨著 App 軟件的大量普及越來越多的企業(yè)也加入到 App  軟件開發(fā)當(dāng)中來,為了盡可能的搶占商機(jī)和提升用戶體驗(yàn),你所在的公司可能也不會把所有的開發(fā)資源都放在 web  應(yīng)用上,而是多端應(yīng)用同時(shí)開發(fā),此時(shí)公司的業(yè)務(wù)線可能就是如下的幾種或者其中一部分:

軟件架構(gòu)之如何理解前后端分離與前端模塊化

瀏覽器端的 Web 應(yīng)用、iOS 原生 App、安卓端原生 App、微信小程序等等,可能只是開發(fā)其中的一部分產(chǎn)品,但是除了 web 應(yīng)用能夠使用傳統(tǒng)的  MVC 模式開發(fā)外,其他的都無法使用該模式進(jìn)行開發(fā),像原生 App 或者微信小程序都是通過調(diào)用 RESTful api 的方式與后端進(jìn)行數(shù)據(jù)交互。

隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,更多的技術(shù)框架被提了出來,其中最革命性的就是前后端分離概念的提出。

什么是前后端分離

何為前后端分離,我認(rèn)為應(yīng)該從以下幾個(gè)方面來理解。

前后端分離是一種項(xiàng)目開發(fā)模式

當(dāng)業(yè)務(wù)變得越來越復(fù)雜或者產(chǎn)品線越來越多,原有的開發(fā)模式已經(jīng)無法滿足業(yè)務(wù)需求,當(dāng)端上的產(chǎn)品越來越多,展現(xiàn)層的變化越來越快、越來越多,此時(shí)就應(yīng)該進(jìn)行前后端分離分層抽象,簡化數(shù)據(jù)獲取過程,比如目前比較常用的就是前端人員自行實(shí)現(xiàn)跳轉(zhuǎn)邏輯和頁面交互,后端只負(fù)責(zé)提供接口數(shù)據(jù),二者之間通過調(diào)用  RESTful api 的方式來進(jìn)行數(shù)據(jù)交互,如下圖所示:

軟件架構(gòu)之如何理解前后端分離與前端模塊化

此時(shí)就不會出現(xiàn) HTML 代碼需要轉(zhuǎn)成 JSP  進(jìn)行開發(fā)的情況,前端項(xiàng)目只負(fù)責(zé)前端部分,并不會摻雜任何后端代碼,這樣的話代碼不再耦合。同時(shí),前端項(xiàng)目與后端項(xiàng)目也不會再出現(xiàn)耦合嚴(yán)重的現(xiàn)象,只要前后端協(xié)商和定義好接口規(guī)范及數(shù)據(jù)交互規(guī)范,雙方就可以并行開發(fā),互不干擾,業(yè)務(wù)也不會耦合,兩端只通過接口來進(jìn)行交互。

在 MVC  模式開發(fā)項(xiàng)目時(shí),往往后端過重,“控制權(quán)”也比較大,既要負(fù)責(zé)處理業(yè)務(wù)邏輯、權(quán)限管理等后端操作,也需要處理頁面跳轉(zhuǎn)等邏輯,在前后端分離的模式中,后端由原來的大包大攬似的獨(dú)裁者變成了接口提供者,而前端也不僅僅是原來那樣僅處理小部分業(yè)務(wù),頁面跳轉(zhuǎn)也不再由后端來處理和決定,整個(gè)項(xiàng)目的控制權(quán)已經(jīng)由后端過渡至前端來掌控,前端需要處理的更多。

前端項(xiàng)目和后端項(xiàng)目隔離開來、互不干涉,通過接口和數(shù)據(jù)規(guī)范來完成項(xiàng)目功能需求,這也是目前比較流行的一種開發(fā)方式。

前后端分離是一種人員分工

在前后端分離的架構(gòu)模式下,后臺負(fù)責(zé)數(shù)據(jù)提供,前端負(fù)責(zé)顯示交互,在這種開發(fā)模式下,前端開發(fā)人員和后端開發(fā)人員分工明確,職責(zé)劃分十分清晰,雙方各司其職,不會存在邊界不清晰的地方,并且從業(yè)人員也各司其職。

前端開發(fā)人員包括 Web 開發(fā)人員、原生 App 開發(fā)人員,后端開發(fā)則是指 Java 開發(fā)人員(以 Java  語言為例),不同的開發(fā)人員只需要注重自己所負(fù)責(zé)的項(xiàng)目即可。后端專注于控制層(RESTful API)、服務(wù)層 、數(shù)據(jù)訪問層,前端專注于前端控制層、  視圖層,不會再出現(xiàn)前端人員需要維護(hù)部分后端代碼,或者后端開發(fā)人員需要去調(diào)試樣式等等職責(zé)不清和前后端耦合的情況,我們通過兩張項(xiàng)目開發(fā)流程簡圖來對比:

軟件架構(gòu)之如何理解前后端分離與前端模塊化

此時(shí),開發(fā)過程中會存在前后端耦合的情況,如果出現(xiàn)問題前端需要返工、后端也需要返工,開發(fā)效率會有所影響?,F(xiàn)在,前后端分離后流程簡圖如下:

軟件架構(gòu)之如何理解前后端分離與前端模塊化

前后端分離后,服務(wù)器端開發(fā)人員和前端開發(fā)人員各干各的,大家互不干擾,。在設(shè)計(jì)完成后,Web 端開發(fā)人員、App  端開發(fā)人員、后端開發(fā)人員都可以投入到開發(fā)工作當(dāng)中,能夠做到并行開發(fā),前端開發(fā)人員與后端開發(fā)人員職責(zé)分離,即使出現(xiàn)問題,也是修復(fù)各自的問題不會互相影響和耦合,開發(fā)效率高且滿足企業(yè)對于多產(chǎn)品線的開發(fā)需求。

前后端分離是一種架構(gòu)模式

前后端分離后,各端應(yīng)用可以獨(dú)立打包部署,并針對性的對部署方式進(jìn)行優(yōu)化,不再是前后端一個(gè)統(tǒng)一的工程最終打成一個(gè)部署包進(jìn)行部署。以 Web  應(yīng)用為例,前端項(xiàng)目部署后,不再依賴于 Servlet 容器,可以使用吞吐量更大的 Nginx  服務(wù)器,采用動靜分離的部署方式,既提升了前端的訪問體驗(yàn),也減輕了后端服務(wù)器的壓力,再進(jìn)一步優(yōu)化的話,可以使用頁面緩存、瀏覽器緩存等設(shè)置,也可以使用 cdn  等產(chǎn)品提升靜態(tài)資源的訪問效率。對于后端服務(wù)而言,可以進(jìn)行集群部署提升服務(wù)的響應(yīng)效率,也可以進(jìn)一步的進(jìn)行服務(wù)化的拆分等等。前后端分離后的獨(dú)立部署維護(hù)以及針對性的優(yōu)化,可以加快整體響應(yīng)速度和吞吐量。

前端發(fā)展歷程

當(dāng)我們?nèi)チ私饽硞€(gè)事物的時(shí)候,首先我們需要去了解它的歷史,才能更好的把握它的未來。

原始時(shí)代

世界上第一款瀏覽器 NCSAMosaic  ,是網(wǎng)景公司(Netscape)在1994年開發(fā)出來的,它的初衷是為了方便科研人員查閱資料、文檔(這個(gè)時(shí)候的文檔大多是圖片形式的)。那個(gè)時(shí)代的每一個(gè)交互,按鈕點(diǎn)擊、表單提交,都需要等待瀏覽器響應(yīng)很長時(shí)間,然后重新下載一個(gè)新頁面。

同年 PHP(超文本預(yù)處理器) 腳本語言被開發(fā)出來,開啟了數(shù)據(jù)嵌入模板的 MVC 模式,同時(shí)期比較類似的做法有以下幾種:

  • PHP 直接將數(shù)據(jù)內(nèi)嵌到 HTML 中。

  • ASP 的 ASPX,在 HTML 中嵌入 C# 代碼。

  • Java 的 JSP 直接將數(shù)據(jù)嵌入到網(wǎng)頁中。

這個(gè)時(shí)期,瀏覽器的開發(fā)者,以后臺開發(fā)人員居多,大部分前后端開發(fā)是一體的,大致開發(fā)流程是:后端收到瀏覽器的請求 ---> 發(fā)送靜態(tài)頁面 --->  發(fā)送到瀏覽器。即使是有專門的前端開發(fā),也只是用 HTML 寫寫頁面模板、CSS  給頁面排個(gè)好看點(diǎn)的版式。在這一時(shí)期,前端的作用有限,往往只是切圖仔的角色。

鐵器時(shí)代

1995年,網(wǎng)景公司的一位叫布蘭登·艾奇的大佬,希望開發(fā)出一個(gè)類似 Java  的腳本語言,用來提升瀏覽器的展示效果,增強(qiáng)動態(tài)交互能力。結(jié)果大佬喝著啤酒抽著煙,十來天就把這個(gè)腳本語言寫出來了,功能很強(qiáng)大,就是語法一點(diǎn)都不像  Java。這樣就漸漸形成了前端的雛形:HTML 為骨架,CSS 為外貌,JavaScript 為交互。

同時(shí)期微軟等一些公司也針對自家瀏覽器開發(fā)出了自己的腳本語言。瀏覽器五花八門,雖然有了比較統(tǒng)一的 ECMA  標(biāo)準(zhǔn),但是瀏覽器先于標(biāo)準(zhǔn)在市場上流行開來,成為了事實(shí)標(biāo)準(zhǔn)。導(dǎo)致,現(xiàn)在前端工程師還要在做一些政府古老項(xiàng)目的時(shí)候,還要去處理瀏覽器兼容(萬惡的 IE  系列)。

不管怎么說,前端開發(fā)也算是能寫點(diǎn)邏輯代碼了,不再是只能畫畫頁面的低端開發(fā)了。隨著1998年 AJax 的出現(xiàn),前端開發(fā)從  Web1.0邁向了Web2.0,前端從純內(nèi)容的靜態(tài)展示,發(fā)展到了動態(tài)網(wǎng)頁,富交互,前端數(shù)據(jù)處理的新時(shí)期。這一時(shí)期,比較知名的兩個(gè)富交互動態(tài)的瀏覽器產(chǎn)品是。

  • Gmail(2004年)

  • Google 地圖(2005年)

由于動態(tài)交互、數(shù)據(jù)交互的需求增多,還衍生出了jQuery(2006) 這樣優(yōu)秀的跨瀏覽器的 js 工具庫,主要用于 DOM  操作,數(shù)據(jù)交互。有些古老的項(xiàng)目,甚至近幾年開發(fā)的大型項(xiàng)目現(xiàn)在還在使用 jQuery,以至于 jQuery 庫現(xiàn)在還在更新,雖然體量上已經(jīng)遠(yuǎn)遠(yuǎn)不及  React、Vue 這些優(yōu)秀的前端庫。

信息時(shí)代

自 2003  以后,前端發(fā)展渡過了一段比較平穩(wěn)的時(shí)期,各大瀏覽器廠商除了按部就班的更新自己的瀏覽器產(chǎn)品之外,沒有再作妖搞點(diǎn)其他事情。但是我們程序員們耐不住寂寞啊,工業(yè)化推動了信息化的快速到來,瀏覽器呈現(xiàn)的數(shù)據(jù)量越來越大,網(wǎng)頁動態(tài)交互的需求越來越多,JavaScript  通過操作 DOM  的弊端和瓶頸越來越明顯(頻繁的交互操作,導(dǎo)致頁面會很卡頓),僅僅從代碼層面去提升頁面性能,變得越來越難。于是優(yōu)秀的大佬們又干了點(diǎn)驚天動地的小事兒:

  • 2008 年,谷歌 V8 引擎發(fā)布,終結(jié)微軟 IE 時(shí)代。

  • 2009 年 AngularJS 誕生、Node誕生。

  • 2011 年 ReactJS 誕生。

  • 2014 年 VueJS 誕生。

其中,V8 和 Node.JS  的出現(xiàn),使前端開發(fā)人員可以用熟悉的語法糖編寫后臺系統(tǒng),為前端提供了使用同一語言的實(shí)現(xiàn)全棧開發(fā)的機(jī)會(JavaScript不再是一個(gè)被嘲笑只能寫寫頁面交互的腳本語言)。React、Angular、Vue  等 MVVM 前端框架的出現(xiàn),使前端實(shí)現(xiàn)了項(xiàng)目真正的應(yīng)用化(SPA單頁面應(yīng)用),不再依賴后臺開發(fā)人員處理頁面路由  Controller,實(shí)現(xiàn)頁面跳轉(zhuǎn)的自我管理。同時(shí)也推動了前后端的徹底分離(前端項(xiàng)目獨(dú)立部署,不再依賴類似的 template 文件目錄)。

至于為啥 MVVM 框架能提升前端的渲染性能,這里簡單的說一下原理,因?yàn)榇罅康?DOM  操作是性能瓶頸的罪魁禍?zhǔn)?,那通過一定的分析比較算法,實(shí)現(xiàn)同等效果下的最小 DOM 開銷是可行的。React、Vue  這類框架大都是通過這類思想實(shí)現(xiàn)的,具體實(shí)現(xiàn)可以去看一下相關(guān)資料。前后端分離也導(dǎo)致前端的分工發(fā)生了一些變化。

軟件架構(gòu)之如何理解前后端分離與前端模塊化

而后端開發(fā)更加關(guān)注數(shù)據(jù)服務(wù),前端則負(fù)責(zé)展示和交互。當(dāng)然相應(yīng)的學(xué)習(xí)成本也越來越大,Node.JS的出現(xiàn)也使得前端前后端一起開發(fā)成為可能,好多大公司在  2015 年前后就進(jìn)行了嘗試,用 Node.JS 作為中間數(shù)據(jù)轉(zhuǎn)接層,讓后端更加專注于數(shù)據(jù)服務(wù)和治理。

前端模塊化發(fā)展歷程

自 2009 年 5 月 Node.js 發(fā)布以來,前端能干的事情越來越多。短短 10  來年的時(shí)間,前端便從刀耕火種的年代走向了模塊化、工程化的時(shí)代。各種前端框架百家爭鳴,前端贏來了真正屬于自己的時(shí)代。

原始時(shí)代

時(shí)間回到  2009年,記得那時(shí)候還沒有流行前后端分離,很多項(xiàng)目還是混在一起,而那時(shí)候的前端開發(fā)人員大多數(shù)也都是“切圖仔”。前端完成靜態(tài)頁面,由服務(wù)端同事完成數(shù)據(jù)的嵌入,也就是所謂的套頁面操作,每當(dāng)有類似的功能,都會回到之前的頁面去復(fù)制粘貼,由于處于不同的頁面,類名需要更換,但是換湯不換藥。

久而久之,重復(fù)代碼越來越多,但凡改動一個(gè)小的地方,都需要改動很多代碼,顯得極不方便,也不利于大規(guī)模的進(jìn)行工程化開發(fā)。雖然市面上也慢慢出現(xiàn)了  Angular、 Avalon 等優(yōu)秀的前端框架,但是考慮到 SEO  和維護(hù)人員并不好招,很多公司還是選擇求穩(wěn),用套頁面的形式制作網(wǎng)頁,這對前端的工程化、模塊化是一個(gè)不小的阻礙。

構(gòu)建工具的出現(xiàn)

不過,隨著 Node 被大力推崇,市面上涌現(xiàn)出大量的構(gòu)建工具,如 Npm  Scripts、Grunt、Gulp、FIS、Webpack、Rollup、Parcel等等。構(gòu)建工具解放了我們的雙手,幫我們處理一些重復(fù)的機(jī)械勞動。

舉個(gè)簡單的例子:我們用 ES6 寫了一段代碼,需要在瀏覽器執(zhí)行。但是由于瀏覽器廠商對瀏覽器的更新非常保守,使得很多 ES6  的代碼并不能直接在瀏覽器上運(yùn)行。這個(gè)時(shí)候我們總不能手動將 ES6 代碼改成 ES5 的代碼。于是乎就有了下面的轉(zhuǎn)換。

//編譯前 [1,2,3].map(item => console.log(item)) //編譯后 [1, 2, 3].map(function (item) {   return console.log(item); }); //代碼壓縮后 [1,2,3].map(function(a){return console.log(a)});

就是做了上述的操作,才能使得我們在寫前端代碼的時(shí)候,使用最新的 ECMAScript  語法,并且盡可能的壓縮代碼的體積,使得瀏覽器加載靜態(tài)腳本時(shí)能更加快速。

傳統(tǒng)的模塊化

隨著 Ajax 的流行,前端工程師能做的事情就不只是“切圖”  這么簡單,現(xiàn)在前端工程師能做的越來越多,開始出現(xiàn)了明確的分工,并且能夠與服務(wù)端工程師進(jìn)行數(shù)據(jù)聯(lián)調(diào)。這里說的傳統(tǒng)模塊化還不是后現(xiàn)代的模塊化,早期的模塊化是不借助任何工具的,純屬由  JavaScript 完成代碼的結(jié)構(gòu)化。在傳統(tǒng)的模塊化中我們主要是將一些能夠復(fù)用的代碼抽成公共方法,以便統(tǒng)一維護(hù)和管理,比如下面代碼。

function show(id) {   document.getElementById(id).setAttribute('style', "display: block") } function hide(id) {   document.getElementById(id).setAttribute('style', "display: none") }

然后,我們將這些工具函數(shù)封裝到一個(gè) JS 腳本文件里,在需要使用它們的地方進(jìn)行引入。

但是,這種做法會衍生出兩個(gè)很大的問題,一個(gè)是全局變量的污染,另一個(gè)是人工維護(hù)模塊之間的依賴關(guān)系會造成代碼的混亂。

例如,當(dāng)我們的項(xiàng)目有十幾個(gè)甚至幾十個(gè)人維護(hù)的時(shí)候,難免會有人在公用組件中添加新的方法,比如 show  這個(gè)方法一旦被覆蓋了,使用它的人會得到和預(yù)期不同的結(jié)果,這樣就造成的全局變量的污染。另一個(gè)問題,因?yàn)檎鎸?shí)項(xiàng)目中的公用腳本之間的依賴關(guān)系是比較復(fù)雜的,比如 c  腳本依賴 b 腳本,a 腳本依賴 b 腳本,那么我們在引入的時(shí)候就要注意必須要這樣引入。

  

要這樣引入才能保證 a 腳本的正常運(yùn)行,否則就會報(bào)錯(cuò)。對于這類問題,我們該如何解決這樣的問題呢?

全局變量的污染

解決這個(gè)問題有兩種,先說說治標(biāo)不治本的方法,我們通過團(tuán)隊(duì)規(guī)范開發(fā)文檔,比如說我有個(gè)方法,是在購物車模塊中使用的,可以如下書寫。

var shop.cart.utils = {   show: function(id) {     document.getElementById(id).setAttribute('style', "display: block")   },   hide: function(id) {     document.getElementById(id).setAttribute('style', "display: none")   } }

這樣就能比較有效的避開全局變量的污染,把方法寫到對象里,再通過對象去調(diào)用。專業(yè)術(shù)語上這叫命名空間的規(guī)范,但是這樣模塊多了變量名會比較累贅,一寫就是一長串,所以我叫它治標(biāo)不治本。

還有一種比較專業(yè)的方法技術(shù)通過立即執(zhí)行函數(shù)完成閉包封裝,為了解決封裝內(nèi)變量的問題,立即執(zhí)行函數(shù)是個(gè)很好的辦法,這也是早期很多開發(fā)正在使用的方式,如下所示。

(function() {     var Cart = Cart || {};    function show (id) {      document.getElementById(id).setAttribute('style', "display: block")    }    function hide (id) {      document.getElementById(id).setAttribute('style', "display: none")    }    Cart.Util = {      show: show,      hide: hide    } })();

上述代碼,通過一個(gè)立即執(zhí)行函數(shù),給予了模塊的獨(dú)立作用域,同時(shí)通過全局變量配置了我們的模塊,達(dá)到了模塊化的目的。

當(dāng)前的模塊化方案

先來說說 CommonJS 規(guī)范,在 Node.JS 發(fā)布之后,CommonJS 模塊化規(guī)范就被用在了項(xiàng)目開發(fā)中,它有幾個(gè)概念給大家解釋一下。

  • 每個(gè)文件都是一個(gè)模塊,它都有屬于自己的作用域,內(nèi)部定義的變量、函數(shù)都是私有的,對外是不可見的;

  • 每個(gè)模塊內(nèi)部的 module 變量代表當(dāng)前模塊,這個(gè)變量是一個(gè)對象;

  • module 的 exports 屬性是對外的接口,加載某個(gè)模塊其實(shí)就是在加載模塊的 module.exports 屬性;

  • 使用 require 關(guān)鍵字加載對應(yīng)的模塊,require 的基本功能就是讀入并執(zhí)行一個(gè) JavaScript 文件,然后返回改模塊的 exports  對象,如果沒有的話會報(bào)錯(cuò)的;

下面來看一下示例,我們就將上面提到過的代碼通過 CommonJS 模塊化。

module.exports = {   show: function (id) {     document.getElementById(id).setAttribute('style', "display: block")   },   hide: function (id) {     document.getElementById(id).setAttribute('style', "display: none")   } } // 也可以輸出單個(gè)方法 module.exports.show = function (id) {   document.getElementById(id).setAttribute('style', "display: block") }  // 引入的方式 var utils = require('./utils') // 使用它 utils.show("body")

除了 CommonJS 規(guī)范外,還有幾個(gè)現(xiàn)在只能在老項(xiàng)目里才能看到的模塊化模式,比如以 require.js 為代表的 AMD(Asynchronous  Module Definition) 規(guī)范 和 玉伯團(tuán)隊(duì)寫的 sea.js 為代表的 CMD(Common Module Definition) 規(guī)范。

AMD 的特點(diǎn):是一步加載模塊,但是前提是一開始就要將所有的依賴項(xiàng)加載完全。CMD 的特點(diǎn)是:依賴延遲,在需要的時(shí)候才去加載。

AMD

首先,我們來看一下如何通過 AMD 規(guī)范的 require.js 書寫上述模塊化代碼。

define(['home'], function(){   function show(id) {     document.getElementById(id).setAttribute('style', "display: block")   }     function hide(id) {     document.getElementById(id).setAttribute('style', "display: none")   }   return {     show: show,     hide: hide   }; });  // 加載模塊 require(['utils'], function (cart){   cart.show('body'); });

require.js 定義了一個(gè)函數(shù) define,它是全局變量,用來定義模塊,它的語法規(guī)范如下:

define(id, dependencies, factory)

  • id:它是可選參數(shù),用于標(biāo)識模塊;

  • dependencies:當(dāng)前模塊所依賴的模塊名稱數(shù)組,如上述模塊依賴 home  模塊,這就解決了之前說的模塊之間依賴關(guān)系換亂的問題,通過這個(gè)參數(shù)可以將前置依賴模塊加載進(jìn)來;

  • factory:模塊初始化要執(zhí)行的函數(shù)或?qū)ο蟆?/p>

require([dependencies], function(){})

然后,在其他文件中使用 require  進(jìn)行引入,第一個(gè)參數(shù)為需要依賴的模塊數(shù)組,第二個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),當(dāng)前面的依賴模塊被加載成功之后,回調(diào)函數(shù)會被執(zhí)行,加載進(jìn)來的模塊將會以參數(shù)的形式傳入函數(shù)內(nèi),以便進(jìn)行其他操作。

感謝各位的閱讀,以上就是“軟件架構(gòu)之如何理解前后端分離與前端模塊化”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對軟件架構(gòu)之如何理解前后端分離與前端模塊化這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!


當(dāng)前題目:軟件架構(gòu)之如何理解前后端分離與前端模塊化
轉(zhuǎn)載來于:http://weahome.cn/article/igjcee.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部