新聞中心
大家好,我是前端西瓜哥。今天來看看前端工程化是什么。

創(chuàng)新互聯(lián)公司專注于劍川網(wǎng)站建設(shè)服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供劍川營銷型網(wǎng)站建設(shè),劍川網(wǎng)站制作、劍川網(wǎng)頁設(shè)計、劍川網(wǎng)站官網(wǎng)定制、微信平臺小程序開發(fā)服務,打造劍川網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供劍川網(wǎng)站排名全網(wǎng)營銷落地服務。
什么是前端工程化?
工程化,可以理解為使用一些方式,去改良然后提高行業(yè)中現(xiàn)有的步驟、設(shè)計、應用方式。前端工程化,就是指對前端進行一些流程的標準化,讓開發(fā)變得更有效率,且更好地做產(chǎn)品交付。
一開始,網(wǎng)頁頁面并不復雜,只是提供一些簡單的展示和交互的靜態(tài)頁面,甚至不需要后端。
后來需要根據(jù)不同用戶返回不同的頁面信息,此時我們會用后端讀取數(shù)據(jù),配合一些模板引擎,在后端拼接好內(nèi)容再返回,這就是所謂的服務端渲染(SSR)。
再后來,頁面變得非常復雜,于是出現(xiàn)了前后端分離,前端被單獨拎了出來,專門寫 html、css 和 js,變成了 單頁面應用(SPA)。但復雜也帶來了很多問題,比如多個腳本的執(zhí)行時機不對、css 名沖突、文件過于臃腫、錯誤的緩存導致沒能下載最新的資源,等前端復雜后出現(xiàn)的一系列問題。
隨著 Nodejs 的誕生,我們可以用 JS 去寫前端工具了。為了解決上面這些問題,前端界出現(xiàn)了一大堆的工具和框架:Gulp、Angular、babel、Sass、React、Vue、Webpack、Yarn、TypeScript、ESLint、Docker、k8s 等等。
一切都是為了讓前端的開發(fā)更工程化,也就是 不停地改良前端項目的開發(fā)流程,讓開發(fā)者能夠更高效地開發(fā)、更好地進行團隊協(xié)作、讓代碼的風格標準化、對資源做壓縮以及懶加載、更好地交付部署等。
(當然也因為工具過多,讓前端直呼 “學不動了”)
我們通過四個維度來談談前端工程化一些具體的細節(jié),分別是:
- 模塊化
- 組件化
- 規(guī)范化
- 自動化
模塊化
模塊化,指的是將代碼功能做拆分,分成獨立地單能相互依賴的片段。
首先是 JS 的模塊化。
JS 一開始的職責是給網(wǎng)頁提供一些簡單的交互,所以語法相對簡單且不支持模塊化。隨著網(wǎng)頁的復雜,發(fā)現(xiàn)原來的組織方式帶來了很多問題,變得難以維護。
于是 CommonJS、AMD、ES Module 等模塊系統(tǒng)出現(xiàn)了。正統(tǒng)標準是 ES Module,通過 import 關(guān)鍵字引入模塊,通過 export 導出模塊。
JS 的模塊化將代碼做了拆分,解決了全局變量污染、依賴關(guān)系不清晰、多人協(xié)作不方便、腳本引入順序、單元測試等問題。
CSS 的模塊化。
?CSS 的第一個問題是比較難寫,比如不支持選擇器嵌套,對此我們可以用 CSS 預編譯器(比如 Less、Sass、Stylus)去寫一些更高級的語法,然后編譯成 CSS。
然后是就 命名沖突問題,一種舊的方案是 BEM,就是通過將 CSS 命名 在組件化的框架中,我們有很多方案,可以用 CSS in JS,也可以用 CSS Module,或者 Vue 特有的 CSS Scoped。
HTML 的模塊化。
html 通常是動態(tài)的,在服務端我們會使用模板引擎(template),將得到的數(shù)據(jù)注入到占位符中。在后端 Nodejs,我們可以用 pug、handlebars、ejs 等。
前后端分離后,我們通常使用的是 Vue 的 template(類似 handlebars 語法)以及 React 的 JSX。
資源整合模塊化
不同類型的資源無法組織在一起,比如 JS 引擎能識別引入的 js 文件,但無法識別 css 文件。如果我們希望所有的資源都能組織再一起進行管理,要分別管理一個個不同類型的資源要方便地多。
為了解決這個問題,webpack 誕生了。webpack 是一個模塊打包器,能夠?qū)⑷魏钨Y源轉(zhuǎn)換為 js 代碼進行導入。比如圖片,它可以先變成一個靜態(tài)資源服務的一個資源,然后在 js 文件 import 的時候在轉(zhuǎn)換為一個 url 字符串,或者直接就變成一個 base64 字符串。
這些需要使用到一些 loader(加載器)。webpack 是一個框架,使用者需要根據(jù)需求,添加一些 loader,去識別不同的文件,轉(zhuǎn)化成 JS 代碼導入。
此外還有 plugin(插件),在這整個流程中做一些處理,比如將導出的 JS 文件插入到 HTML 模板中,或是進行代碼的壓縮等等。
組件化
組件化是 UI 層面上的更細粒度的拆分,一種類似 div 等原生元素的 “自定義元素”。
組件有自己的 HTML、CSS 和 JS,同時有自己的狀態(tài),并支持嵌入到其他組件中并接受外部的數(shù)據(jù),可以進行復用。組件化可以看作是 UI 層組織方式的一種模塊化。
目前主流的 React 和 Vue 前端框架都是基于組件的。
原本的以資源類型為單位進行組織的管理(所有 JS 文件放一個文件夾、CSS 同理),其實維護起來比較困難,也不好復用,組件化的構(gòu)想是以視覺為單位進行拆分,做了結(jié)構(gòu)、樣式、腳本的組裝,抽象出一個 “新的元素”。
組件已經(jīng)是前端開發(fā)的基石了,是一種比較合理的抽象。
規(guī)范化
然后就是前端代碼的規(guī)范。規(guī)范是很重要的,能讓代碼能夠?qū)懙酶菀赘_,避免一些不必要的錯誤。
能想到的規(guī)范有:
- 目錄結(jié)構(gòu)規(guī)定。
- 代碼風格(包括 JS、HTML、CSS)。
- 注釋規(guī)范。
- commit message 規(guī)范。
- git 工作流規(guī)范。
- Code Review。
- 請求接口規(guī)范。
有些規(guī)范不太能用工具進行限制,比如目錄結(jié)構(gòu)。但有些規(guī)范是可以利用到工具的,下面來說說有哪些和規(guī)范相關(guān)的工具。
首先是重磅級的 TypeScript。
TS 是有類型的 JS,是 JS 的超集。通過類型,我們可以預測變量的行為,比如一個布爾值類型是不能被作為函數(shù)調(diào)用的,可能為 undefined 的值需要進行類型收窄后丟棄 undefined 的可能性才能使用。
TS 越來越流行,是因為在大型項目中,類型系統(tǒng)是非常重要的,能夠避免大量的類型錯誤。TS 讓代碼即文檔,降低程序員理解代碼的成本。
如果工具層就能做規(guī)范,就不應該用文檔去說明,人不是絕對正確的機器,但工具可以。
然后是 ESLint。
ESLint 能夠檢測 JS 代碼中的錯誤,主要兩個方面:
- 代碼質(zhì)量,比如你不能聲明一個沒有被使用的變量。
- 代碼風格,比如字符串引號必須用單引號。
ESLint 有助于統(tǒng)一團隊的風格,讓代碼看起來基本像是一個人寫的,避免出現(xiàn)字符串一會用單引號,一會用雙引號,變量命名一會用下劃線風格,一會用駝峰風格,這種讓強迫癥抓狂的情況。
然后是 commit message。commit message 我們不希望看到像是 “修復了一些 bug” 這種不夠具體的寫法,希望具有一定的結(jié)構(gòu),比如 "fix(工作臺): 修復了卡片不能滾動的問題"。
對此我們可以用 commitlint 的命令行工具去判斷是否符合特定風格。
當然還需要確保團隊成員是使用了這些工具的,我們可以用保存后自動格式化(需要配合編輯器和對應插件)。然后最重要的就是 git hook,可以在本地 commit 時先對 staged 中的文件做風格校驗和格式化,然后再檢查 commit messge 風格是。如果不對,本地 commit 會失敗。對應的工具是 husky。
自動化
重復的可以自動化的流程化工作,應該盡量去自動化。讓人去做,對人是一種折磨,然后也不能保證質(zhì)量,因為通常流程也很復雜,即使是簡單,做多了也容易錯。
一個小概率事件只要做的次數(shù)足夠多,它就會變成大概率事件。這也是為什么分布式系統(tǒng)中容錯機制是非常重要的原因。
首先想到的自然是 CI/CD(持續(xù)集成和持續(xù)交付/部署)。我們將代碼提交到遠端倉庫時,或者是給一個分支打了 tag 后,能夠觸發(fā)一些腳本,將我們的項目代碼做打包編譯,發(fā)布成制品,然后發(fā)布到生產(chǎn)環(huán)境。這些都是自動化的,流程化的。
CI/CD 工具有很多:Jenkins(比較古老了)、GitLab CI/CD、GitHub Action、Docker(發(fā)布制品) 和 k8s(容器編排)等。
前面說的 git hook,在本地 commit 時進行一些操作,也算是一種簡單的自動化。
打包工具
前端工程化的核心是打包工具。
打包工具需要支持的 幾種重要的能力:
- 代碼分割:指的將代碼劃分為可以按需 / 同時加載的多個bundles 或組件的能力。比如動態(tài) import、提取公共依賴模塊代碼、多個入口文件沒有重復代碼、支持 ESM 的值引用模擬等。
- 哈希:資源更新時做哈希,防止資源緩存。哈希分很多種,比如文件路徑名哈希、內(nèi)容哈希等。
- 包引入:ES Module、CommonJS 以及從 node_modules 目錄引入包的支持。
- 非 JS 資源:導入非 JS 資源的支持,像是 webpack 需要使用各種 loader 來支持,有些打包工具是內(nèi)置的。
- 輸出的模塊格式:支持導出為 ES Module、CommonJS 等模塊。
- 轉(zhuǎn)換處理:比如對圖片壓縮、代碼壓縮、JS 版本降低等,在 webpack 中是使用 plugins 來實現(xiàn)的。
其他
還有一些零散的可以提高效率的工具。
- babel:開發(fā)時使用高版本的 ES 語言特性,然后生產(chǎn)環(huán)境用 babel 轉(zhuǎn)換為低版本的兼容性好的 ES5。打包工具內(nèi)部其實使用了 babel。
- tsc:tsc(TS 編譯工具) 在支持 TS 的前提下,也支持編譯為 JS 低版本。
- polyfill:低版本的 ES5,想要使用一些新的 API,可以自己寫函數(shù)去模擬,這就是 polyfill,通常我們會使用 core.js 庫,但有些語言層面上的新特性就不能用 polyfill。
- monorepo:將多個項目放到一個 git 倉庫下,方便包的依賴共用和維護。
- 異常監(jiān)控:當前端報錯時,將相關(guān)信息提交到異常監(jiān)控服務,比如 sentry,通常配合 sourcemap 精確定位源碼中的錯誤位置。
- 制品庫:使用 Nexus 來部署自己的私有制品庫,支持各種制品庫。比如發(fā)布 docker 包、npm 包等,配合發(fā)版部署;
- VSCode Snippet:自定義 VSCode 編輯器的代碼片段,可以快速生成一些預置好的代碼模板,減少一些模板代碼的書寫??梢詺w為自動化。
- Mock:前端在后端確認返回數(shù)據(jù)結(jié)構(gòu)后完成接口前,可以通過模擬虛假數(shù)據(jù)進行調(diào)試開發(fā),比如 yapi 平臺就是除了支持接口文檔,還提供 mock 功能。
- 單元測試:以模塊(比如組件)為單位進行測試,保證代碼邏輯符合預期。單元測試通常比較耗時,會在提交到遠端時或合并到主分支時進行。流行的單元測試庫有 Jest。
- 熱重載:因為每次改代碼都要編譯,如果整個項目都要重新編譯開發(fā)體驗很差,可以用熱重載只編譯被修改的模塊。
- 組件庫文檔:可以用 stroybook。如果是 vue 組件,可以考慮用 Vue Press。
- Tree shaking:丟掉一些引入了但沒有使用的模塊。
結(jié)尾
簡單來說,前端工程化是對前端開發(fā)流程的改良,是效率工具。
網(wǎng)頁名稱:前端工程化指的是什么?
轉(zhuǎn)載來源:http://fisionsoft.com.cn/article/dhhdiij.html


咨詢
建站咨詢
