web應(yīng)用復(fù)雜度的增加,特別是單頁(yè)面應(yīng)用的風(fēng)靡。組件化,工程化,自動(dòng)化成了前端發(fā)展的趨勢(shì)?;蛘哒f(shuō)一線的互聯(lián)網(wǎng)公司就是這么做的。
每個(gè)網(wǎng)站制作團(tuán)隊(duì)都在打造自己的前端開(kāi)發(fā)體系,這通常是一個(gè)東拼西湊,逐漸磨合的過(guò)程,在技術(shù)發(fā)展日新月異的今天,這樣的過(guò)程真的是不可抽象和復(fù)制的么?
一、webpack
目前市場(chǎng)上流行的前端工具大體分為3類,分別介紹如下。
1.工作流管理工具,比如Grunt、Gulp。
2.構(gòu)建工具,比如webpack、rollup。
3.整體解決方案,比如FIS、WeFlow。
FIS是一套比較完整的前端工程化方案,它具備構(gòu)建、部署、Mock服務(wù)等基本功能,但其構(gòu)建功能對(duì)于目前市場(chǎng)較流行的技術(shù)支持度不是很理想,需要編寫(xiě)插件實(shí)現(xiàn)。而且其生態(tài)圈不夠龐大,插件數(shù)量和質(zhì)量均堪憂。此外,F(xiàn)IS誕生的初始目標(biāo)是解決百度團(tuán)隊(duì)的內(nèi)部需求,不論是從功能的完整度還是對(duì)編程范式的約束上,均有一定的局限性和捆綁性,比如FIS實(shí)現(xiàn)自動(dòng)生成CSS Sprites圖的功能需要開(kāi)發(fā)者在代碼中注入特殊標(biāo)記,這在一定程度上限制了代碼的可移植性。
Grunt、Gulp之類工作流管理工具本身不提供任何具體功能,所有的構(gòu)建、部署等功能均由對(duì)應(yīng)的插件提供。這便于項(xiàng)目各環(huán)節(jié)工作流程的控制,比如構(gòu)建功能可以安排首先構(gòu)建CSS和JS,然后構(gòu)建HTML。Grunt和Gulp各自的生態(tài)圈也比較完整,但它們逐漸有了衰退之勢(shì)。圖1是來(lái)自Stack 0verflow Trends的數(shù)據(jù)。
圖1
Grunt、Gulp相關(guān)的討論話題與webpack相比下落趨勢(shì)明顯。webpack雖然是近兩年才崛起的構(gòu)建工具,但其迅速發(fā)展為目前最流行的構(gòu)建工具之一。其生態(tài)圈的龐大程度相比Grunt、Gulp有過(guò)之而無(wú)不及,與FIS相比更是拉開(kāi)了數(shù)量級(jí)的差距,而且React、Vue等較流行的框架對(duì)應(yīng)的webpack Loader均是由官方或者作者本人編寫(xiě)的,可保證插件的質(zhì)量和更新的及時(shí)性。即使生態(tài)圈沒(méi)有你所需的插件,webpack也提供了優(yōu)雅的生命周期和高度擴(kuò)展的API,便于開(kāi)發(fā)各類插件。此外,webpack在提供足夠多的構(gòu)建功能的同時(shí)兼具性能優(yōu)化,比如對(duì)構(gòu)建產(chǎn)出文件的體積進(jìn)行監(jiān)控、其v2版本引入的Tree Shaking機(jī)制等。這也是我們選擇webpack作為構(gòu)建內(nèi)核的原因之一。rollup也是一款非常優(yōu)秀的構(gòu)建工具,但由于起步較晚,目前生態(tài)還不完整。
二、工程化方案的整體架構(gòu)
本地工具鏈和云管理平臺(tái)形態(tài)的前端工程化方案的主要區(qū)別在于,將構(gòu)建、部署功能提升到云平臺(tái)集中管理,保證構(gòu)建結(jié)果的一致性并且便于權(quán)限控制,而從各個(gè)功能模塊的實(shí)現(xiàn)角度考慮并沒(méi)有很大差別。所以本書(shū)以本地工具鏈形態(tài)的前端工程化方案Boi為一致性并且便于權(quán)限控制,而從各個(gè)功能模塊的實(shí)現(xiàn)角度考慮并沒(méi)有很大差別。所以本書(shū)以本地工具鏈形態(tài)的前端工程化方案Boi為例,剖析各功能模塊的設(shè)計(jì)方案和實(shí)現(xiàn)細(xì)節(jié),同時(shí)在論述過(guò)程中兼顧云平臺(tái)的差異性對(duì)比及其解決方案。整體架構(gòu)如圖1-11所示。
·暴露給用戶層的有兩種接口:命令行調(diào)用各功能模塊的接口和配置接口。
·平臺(tái)層分為4個(gè)功能模塊:腳手架、本地服務(wù)器、構(gòu)建以及部署模塊。
·內(nèi)核層是各個(gè)功能模塊的內(nèi)核,腳手架使用Yeoman,本地服務(wù)由Node.js的Express框架承載,構(gòu)建功能模塊圍繞webpack打造,部署基于SSH協(xié)議實(shí)現(xiàn)。
·以上所有的功能實(shí)現(xiàn)均是建立在Node.js平臺(tái)上的。
Boi是一款開(kāi)源的前端工程化方案,讀者可以在GitHub(https://github.com/boijs/boi)中獲取其源碼。
請(qǐng)注意,我們的重點(diǎn)并不是具體的代碼實(shí)現(xiàn)細(xì)節(jié),而是通過(guò)具體案例探討前端工程化方案應(yīng)該具備的功能以及設(shè)計(jì)原則。以上的具體架構(gòu)和方案只是作為輔助,目的是為了便于論述和理解。
三、功能規(guī)劃
根據(jù)如圖2所示的工程化整體架構(gòu),平臺(tái)層分為4個(gè)功能模塊。
圖2 平臺(tái)層的4個(gè)功能模塊
·以Yeoman為內(nèi)核的腳手架。
·以Express承載的本地服務(wù)器。
·以webpack為內(nèi)核的構(gòu)建系統(tǒng)。
·基于SFTP協(xié)議的遠(yuǎn)程部署功能。
1.命令行工具
得益于龐大的生態(tài)圈,使用Node.js開(kāi)發(fā)命令行工具并不是一件難事,我們可以借助優(yōu)秀的輔助工具完成,比如commander.js。
首先在package.json文件中聲明bin字段指向項(xiàng)目中的入口文件:
其中key的值"boi”便是命令行工具的主命令,value值"bin/boi.js”指向的是此命令調(diào)用的文件路徑。
然后在"bin/boi.js”文件中的頂部聲明此文件需要調(diào)用Node.js執(zhí)行:
#!/usr/bin/env node
隨后就可以使用commander.js定制具體的子命令了。以build命令為例:
commander.js是一個(gè)實(shí)現(xiàn)命令行交互的Node.js模塊,由著名的工程師TJHolowaychuk編寫(xiě)。更多使用細(xì)節(jié)讀者可以參考commander.js的官方文檔。
根據(jù)前文所述的功能規(guī)劃,各功能對(duì)應(yīng)的命令行命令如表1所示。
表1
2.構(gòu)建功能規(guī)劃
構(gòu)建系統(tǒng)是整個(gè)工程化方案中最重要也是最復(fù)雜的功能,主要解決的是前端開(kāi)發(fā)層面的問(wèn)題。工程化方案Boi將內(nèi)置以下功能。
·ES規(guī)范的轉(zhuǎn)譯。
·CSS預(yù)編譯器支持。
·PostCSS處理hack后綴。
·自動(dòng)創(chuàng)建CSS Sprites圖。
·圖片壓縮。
·小體積圖片base64內(nèi)嵌。
·JavaScript模塊化規(guī)范支持。
除以上功能以外,Boi針對(duì)不同的緩存策略可以支持增量更新與覆蓋更新構(gòu)建。
3.環(huán)境區(qū)分
一個(gè)前端項(xiàng)目的迭代周期自始至終需要經(jīng)歷3個(gè)階段:開(kāi)發(fā)、測(cè)試和部署上線。每個(gè)階段對(duì)應(yīng)的運(yùn)行環(huán)境為開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境和生產(chǎn)環(huán)境。不同的運(yùn)行環(huán)境存在差異性的同時(shí),對(duì)工程化方案的需求也不盡相同,比如開(kāi)發(fā)環(huán)境需要借助Mock服務(wù)進(jìn)行前端邏輯的開(kāi)發(fā)、構(gòu)建產(chǎn)出的代碼需要便于瀏覽器調(diào)試,測(cè)試環(huán)境與生產(chǎn)環(huán)境的異步數(shù)據(jù)接口地址不同,生產(chǎn)環(huán)境需要控制靜態(tài)文件體積等。工程化方案需要針對(duì)3種運(yùn)行環(huán)境提供相應(yīng)的功能和策略,必然會(huì)將環(huán)境相關(guān)的配置開(kāi)放給用戶。Boi將3種環(huán)境具化為3個(gè)不同配置API。
.dev——開(kāi)發(fā)環(huán)境。
·testing——測(cè)試環(huán)境。
·prod——生產(chǎn)環(huán)境。
3種環(huán)境的執(zhí)行時(shí)機(jī)分別如表2所示。
表2

用戶可以通過(guò)配置API針對(duì)不同的環(huán)境分配對(duì)應(yīng)的功能和策略,隨后使用命令行工具指定執(zhí)行環(huán)境。比如測(cè)試環(huán)境使用如下配置不對(duì)JavaScript代碼進(jìn)行混淆處理:
其中boi.spec是Boi提供的配置API。開(kāi)發(fā)完成之后,運(yùn)行以下命令構(gòu)建測(cè)試環(huán)境代碼:
boi build--env testing
最終構(gòu)建產(chǎn)出的JavaScript代碼不會(huì)經(jīng)過(guò)混淆。
對(duì)環(huán)境配置功能最直觀的理解是針對(duì)不同運(yùn)行環(huán)境構(gòu)建產(chǎn)出不同的代碼內(nèi)容。具體到使用層面可以與本地服務(wù)器、Mock服務(wù)、構(gòu)建、部署功能模塊聯(lián)動(dòng),打造一種類似沙箱的獨(dú)立作業(yè)環(huán)境,目的是解放生產(chǎn)力,同時(shí)保證整個(gè)開(kāi)發(fā)流程的嚴(yán)謹(jǐn)性和代碼質(zhì)量。
四、設(shè)計(jì)原則
1.規(guī)范設(shè)計(jì)原則——用戶至上
規(guī)范分為兩部分:工程化方案自身的配置API規(guī)范以及方案對(duì)代碼編程范式的約束規(guī)范。
配置API的設(shè)計(jì)原則著重于配置項(xiàng)的簡(jiǎn)潔明了,配置項(xiàng)可以一目了然。本書(shū)所介紹的工程化方案Boi使用webpack作為構(gòu)建內(nèi)核,在其外層封裝了一層簡(jiǎn)化的配置API。webpack自身的優(yōu)異性不用贅述,但是配置復(fù)雜度非常高,并且webpack自身不提供任何具體的構(gòu)建方案,用戶需要自行配置并安裝各種loader、plugin來(lái)封裝符合項(xiàng)目需求的具體方案。開(kāi)發(fā)者往往需要花費(fèi)大量的時(shí)間
習(xí)和處理webpack本身的配置,這顯然是非常影響開(kāi)發(fā)效率的。Boi以外部簡(jiǎn)化的配置API映射內(nèi)部高度復(fù)雜化的webpack配置,不僅降低了一線業(yè)務(wù)開(kāi)發(fā)人員對(duì)構(gòu)建工具本身的學(xué)習(xí)成本,還避免了在進(jìn)行自身迭代以及問(wèn)題修復(fù)過(guò)程中增加的遷移成本。
編程規(guī)范的設(shè)計(jì)原則著重于代碼的可移植性,減少對(duì)代碼的捆綁性。比如前文提到的FIS在實(shí)現(xiàn)CSS Sprites功能時(shí)需要開(kāi)發(fā)者在代碼中添加可被FIS識(shí)別的特殊標(biāo)記。如果項(xiàng)目需要遷移到其他構(gòu)建方案中,這類特殊標(biāo)記便成為冗余代碼,不僅影響代碼的可讀性,而且不能保證與新的構(gòu)建方案不存在沖突。工具只是輔助作用,最基本的原則是切勿喧賓奪主。
2.架構(gòu)設(shè)計(jì)原則——擴(kuò)展至上
除能夠解決現(xiàn)階段的功能需求以外,對(duì)隱含需求的支持度也是評(píng)估一套工程化方案的標(biāo)準(zhǔn)之一。即使出現(xiàn)新需求時(shí)目前方案不支持,也能夠以很小的成本對(duì)方案進(jìn)行擴(kuò)展。前端資源以及技術(shù)選型的多樣性,令可擴(kuò)展性對(duì)于前端工程化方案來(lái)說(shuō)尤為重要。我們?cè)谠O(shè)計(jì)工程化方案架構(gòu)時(shí),應(yīng)當(dāng)秉持“內(nèi)核輕量、擴(kuò)展豐富”的原則。比如webpack本身不提供任何具化的方案,而是開(kāi)放豐富的配置和擴(kuò)展API供開(kāi)發(fā)者封裝和擴(kuò)展自己的構(gòu)建方案。本書(shū)所介紹的工程化方案Boi自身只封裝了必要的功能,比如ES轉(zhuǎn)譯、CSS預(yù)編譯器支持等,對(duì)于目前流行的框架如React、Vue并不支持。但是你可以通過(guò)Boi的插件系統(tǒng)以非常小的成本對(duì)Boi進(jìn)行擴(kuò)展,并且這些插件是即插即用的,不會(huì)對(duì)Boi內(nèi)核產(chǎn)生任何影響。
今天的網(wǎng)頁(yè)制作分享就到這了,如果您喜歡這篇文章,您可以分享給你的朋友!深圳網(wǎng)站建設(shè)-博納網(wǎng)絡(luò)編輯整理。