雖然前端工程化的概念興起還沒幾年的時間,可是對於「工程化」這個詞並非一個新鮮詞了,在其餘軟件開發的領域很早就已經有了高度的工程化,例如Web服務端開發。只不過那個時候,前端工程師並無工程化的意識,也沒有必要對前端進行工程化的操做,畢竟在那個時期,前端的開發工做只能算是整個項目開發過程當中的「附屬品」。那爲何這幾年,前端工程化的概念又忽然成爲了熱點話題了呢?要想講好前端工程化其實並不容易,我就從下面幾個方面入手,對前端工程化的概念作個簡單的講解,僅僅是我的理解,但願你們多多交流討論。css
一、前端爲何要工程化?html
在回答前端工程化這個問題以前,咱們應該先考慮另一個問題:前端開發中會不會涉及到業務?再詳細一點,就是前端工程師到底需不須要了解服務端的業務邏輯,再或者說,要不要將一部分服務端的業務邏輯放到前端來實現。這個問題沒有標準的答案,實際上應該屬於工程協做問題,就是誰該幹什麼的問題。前端
最先的前端開發就是實現頁面,頂多再寫寫JS讓頁面能夠有交互的特效。可是隨着需求的增長,咱們不只要作Web應用,還要作App、小程序以及各類端。在這種需求日增的狀況下,必須得考慮一種新的方式,優化前端的開發工做,例如,解決代碼冗餘,項目可維護性,提高版本迭代速度等等一系列的問題。前端工程化的概念也就是在這中狀況下被提出了。html5
二、實現前端工程化的基礎——先後端分離web
實際上,如今的前端工程化應該還處於早期階段,畢竟前端工程師這個崗位也才誕生沒幾年。在互聯網發展的早期,Web應用不少狀況下都是由服務端工程師一肩挑,前端開發頂可能是寫寫HTML代碼,實現頁面的佈局,而後再把寫好的HTML靜態文件交給後端工程師套模板,由於當時大部分的Web應用都是使用的服務端渲染技術,例如Java的JSP。編程
這種傳統模式下的協做開發效率很是低,若是在頁面測試中發現了一個bug,這個bug是因爲一個ClassName的值少寫了一個字母,你說這種狀況究竟是前端工程師的錯,仍是後端工程師套模板時的粗枝大葉呢?畢竟一個網站上有成千上萬個DOM節點,誰也不能保證一行代碼都不會寫錯。再假如,項目上線後發現網頁的實際像素和設計稿上存在1像素的誤差,這個時候就須要由前端工程師從新設計一次HTML靜態頁面,而後再交給後端工程師繼續套模板,等整個流程走完以後,你會發現一個更加嚴重的問題,整個項目中僅僅是1像素的誤差,就有可能要調動整個開發團隊來處理這1像素的問題,極大的浪費了團隊資源。小程序
上面的問題也僅僅是傳統開發問題中的冰山一角,面對這麼多的問題,先後端分離開發也就應運而生了。先後端分離開發,爲前端工程化的發展提供了生存的土壤。隨着市場需求的不斷變化,前端開發從傳統的WebPage模式,轉變到WebApp模式,Web產品形態的變化也不斷推進着前端工程師的工做內容發生變化。在應對各類「變化」,前端工程師們也要設計出本身的前端開發「方法論」。後端
前端工程化的主要目標就是解放生產力、提升生產效率。經過制定一系列的規範,藉助工具和框架解決前端開發以及先後端協做過程當中的痛點和難度問題。前端工程化
三、如何實施前端工程化?瀏覽器
明確先後端開發的分工,是實現先後端分離的第一步,也是後面實現前端各類優化方案的基礎。前端工程師主要負責的內容包括:
靜態資源和動態資源的處理;
JavaScript實現前端業務邏輯;
HTML模板文件的產出;
中間層Web服務,通常由Node.js實現;
前端單元測試;
前端項目部署;
其中,靜態資源包括.js文件、.css文件以及各類格式的圖片、媒體文件等,這些文件不依賴於服務器,只須要在瀏覽器裏面解析就能夠了;動態資源是指HTML的模板,若是項目不是由服務器完成渲染的SPA(單頁面)應用,那咱們就要考慮如何實現HTML模板的渲染了。前端項目部署是指靜態資源文件在測試服務器上的部署,以及HTML模板文件在Node.js中間層服務器上的部署。
從項目開發的總體環節來講,實現前端工程化還須要熟練掌握下面幾個方面:
(1)使用Webpack實現項目構建
構建,簡單來講就是編譯,前端開發的全部文件最終歸屬是要交給瀏覽器去解析、渲染,並將頁面呈現給用戶,構建就是將前端開發中的全部源代碼轉化爲宿主瀏覽器能夠執行的代碼。前端構建產出的資源文件只有三種,HTML、CSS、JS文件。須要完成編譯的內容有:
沒法被瀏覽器直接識別的JS代碼,包括ES6/7/8/9/10等符合ECMAScript規範的JS代碼;
沒法被瀏覽器直接識別的CSS代碼,包括SASS/LESS等預編譯的CSS語法;
沒法被瀏覽器識別的HTML模板代碼,包括jade、ejs、artTemplate、mustache等Node.js模板引擎;
項目構建其實就是爲了彌補瀏覽器自身的缺陷和不足,是一種面向語言的編譯過程。那麼,除了針對語言自己以外,前端的構建還應該考慮到Web應用的性能優化。這些優化主要是爲了減小HTTP請求,提高用戶體驗,包括:
依賴打包,將同步依賴的文件打包在一塊兒,減小HTTP請求數量;
資源嵌入,例如將小於10kb的圖片編譯爲base64格式嵌入文檔,減小HTTP請求;
文件壓縮,減小文件體積,縮短請求時間;
爲文件加入hash指紋,以應對瀏覽器緩存策略;
將開發環境下的域名與靜態資源文件路徑修改成生產環境下的域名和路徑;
文件名稱的改變;
這裏須要解釋一下,前端的構建工具除了Webpack以外,還有其餘的工具,例如Gulp、Grunt等,爲何這裏只提到了Webpack?其實,Gulp、Grunt只能算是工做流管理工具,它們自己是不提供具體的功能,全部的構建、部署等功能都要由對應的插件來完成,使用Gulp和Grunt只是便於項目各個環節工做流程的控制。並且,這兩款工具的話題熱度和使用率遠不及Webpack,Webpack雖然是近兩年才崛起的構建工具,但目前依然成爲了最流行的構建工具之一,Vue和React兩大前端框架的Webpack Loader也是有官方或做者本人編寫的。因此,咱們在講前端工程化構建時,推薦使用Webpack這款工具。
(2)使用Babel完成JavaScript編譯
JavaScript能夠說是前端最爲核心的一門編程語言了,也就是咱們常說的「JS」,JS自己是能夠直接在瀏覽器中執行的,那麼爲何還要使用Babel再編譯一次呢?其實,這裏要解釋一下,在ECMAScript2015(簡稱ES6)正式發佈之後,前端工程師關注的重心就由「JS」轉向了「ES」,做爲專業的前端工程師們應該都瞭解,JavaScript ≠ ECMAScript。
ECMAScript是一個標準,JavaScript是對ECMAScript標準實現的一個子集。宿主瀏覽器的API(BOM和DOM)再加上JavaScript,就組成了咱們傳統認知中的JavaScript。可是隨着ECMAScript的版本不斷迭代更新,帶來的並非開發的便利,因爲瀏覽器對ECMAScript新規範的支持實現比較滯後,即便是目前最新版的Chrome瀏覽器也沒有徹底支持ECMAScript2015(ES6)的全部規範,並且ECMAScript2017都已經發布了,爲了更好的讓新的ES規範可以無縫銜接瀏覽器,Babel編譯JavaScript語法的做用就突顯出來了。
Babel的做用簡單來講,就是將瀏覽器未實現的ECMAScript規範語法轉化爲可運行的低版本語法,例如將ES6的class轉化爲ES5的prototype實現。
(3)CSS預編譯
CSS做爲瀏覽器能夠直接識別的樣式語言,彌補了HTML原生樣式的不足,對於早期互聯網開發中,樣式的要求並不複雜,僅須要少許的CSS代碼便可。可是在現在追求用戶極致體驗的潮流下,CSS的開發要求不斷提升,複雜的CSS開發變成一件很是繁瑣和痛苦的事情。最主要的緣由仍是受限於瀏覽器的實現和CSS自身的弱編程能力。
CSS預編譯器的工做原理是提供便捷的語法和特性供開發者編寫源代碼,隨後通過專門的編譯工具將源碼轉化爲CSS語法。
(4)模塊化開發
模塊化開發和組件化開發是兩個徹底不一樣的概念,模塊化屬於架構層面的概念,前端工程化與模塊化的關係就相似於組裝車間與零件的關係。使用模塊化開發,能夠解決下面幾個問題:
避免命名衝突;
便於依賴管理;
利於性能優化;
提升可維護性;
提升代碼可複用性;
在ES6規範發佈以前,前端模塊化開發主要有三種規範,分別是:CommonJS、AMD、CMD。
CommonJS是一種只適用於JavaScript的靜態模塊化規範,適合Node.js開發,但並不適合瀏覽器環境;而AMD/CMD規範並非徹底一致的,但核心功能是統一的,兩個規範都重點解決了瀏覽器對前端模塊化的需求。
ES6 Module規範推出以後,前三者的模塊化規範也逐漸退出前端的歷史舞臺。ES6 Module是語言層面的規範,與應用場景無關,因此一個不涉及運行環境API調用的模塊能夠在任何場景下運行。可是目前瀏覽器尚未徹底支持這種規範,因此,要實現ES6 Module規範的話,還須要使用構建工具進行編譯。
(5)組件化開發
前面提到了,組件化和模塊化是兩個徹底不一樣的概念,模塊化是文件層面上對代碼和資源的拆分,組件化是設計層面上對UI的拆分。從UI中拆分出來的一個結構單元,成爲UI組件,一個UI組件單元包含了HTML模板、CSS樣式、JS邏輯。在頁面的設計過程當中,頁面上的每個元素都是組件,頁面也是一個組件,只不過頁面是一個大型組件,而後這個大型組件又由多箇中小型組件拼裝而成。中型組件還能夠再拆分紅小型組件,小型組件再拆分紅DOM元素,DOM元素也屬於瀏覽器自身的組件,是組件的基本單元。這種組件化開發就是前端開發的「分治思想」。
(6)開發環境的本地服務器與Mock服務
在前端工程化開發中,經過構建工具能夠將代碼進行編譯,而後在瀏覽器中進行調試,可是在開發過程當中源碼的每次修改都須要執行一次構建,構建完成後才能在瀏覽器裏運行,這對前端工程師來講無疑就是一種災難。要完美的解決這個問題,可使用本地服務器與構建工具結合,對源碼進行監聽並在修改以後觸發動態構建,使用自動化構建的方式代替人工。這種動態構建是使用本地服務器解決開發層面上的問題。
Mock服務解決的是先後端協做開發的問題,先後端開發人員提早約定好規範,前端工程師經過本地服務器提供的Mock數據接口輔助前端邏輯的編寫和功能模塊的開發。若是項目中須要服務器端渲染(***),本地服務器還須要具有解析HTML模板的能力,同時Mock服務提供***所需的初始化數據。
前端工程師可使用本地服務器提供的Mock數據接口,在後端人員開發的同時,進行前端邏輯的並行開發,等到後端真實接口開發完成後,將前端請求的地址從Mock服務遷移到服務器的生產環境便可。
(7)規範化約束
不管是服務器端開發仍是前端工程化開發,規範化的約束都相當重要。開發人員在設計項目的總體架構時,爲了考慮到項目的可擴展性、可維護性、高內聚性等因素,會對代碼進行封裝,使用配置化操做,爲項目開發帶來便利,這必然要求業務代碼編程範式遵循既定的約束。這種約束雖然帶來了開發上的便捷,可是在必定程度上制約了代碼的可移植性。例如,在項目中使用了某個構建工具來解決項目需求,可是若是有一天項目須要更換另外一個構建工具時,代碼中原有的構建工具的配置會成爲冗餘代碼,並且不能保證這類配置不會對新構建工具產生衝突。即使是沒有產生衝突,對代碼的性能優化也是會帶來必定負面影響的。工程化方案做爲一種服務,應該儘可能下降對項目產生的負面影響。這是制定編程範式約束規範時最重要的考慮因素。
(8)項目部署流程化
站在前端開發的範疇來講,項目部署是指前端開發人員將構建產出的代碼包部署到測試服務器的過程,而並不是是將測試完成的代碼發佈到生產環境的過程。在部署過程當中,要考慮目標服務器、路徑信息是否與項目一一對應,而且可供負責部署到生產環境的開發人員進行配置,部署的操做流程應儘可能簡單。
在部署流程中,使用命令行取代工具執行(例如FTP)本地部署,可以極大的提升部署的速度和效率,可是這只是初級階段的部署流程。考慮團隊協做和安全方面的因素,最佳的方式應該是搭建一個可供嚴格審查、隊列控制、操做簡化的部署平臺,而且有專人負責掌握流程進度。雖然這種搭建部署平臺的方式在必定程度上減緩了總體的部署速度,可是增強了團隊協做和安全保障。
四、前端工程化將來的發展如何?
目前,Web應用開發的分工模式還處於探索期,並且從最近流行的「大前端」的趨勢來看,前端工程師的發展或許會突破Web領域,向多端領域發展,例如React Native、Weex、Electron、小程序等。從誕生之初「切圖仔」到大前端概念,前端工程師的定位和負責的技術範疇一直在變化,可是前端工程師產出的服務對象永遠是用戶。在Node.js以前,瀏覽器是前端工程師生存的「一畝三分地」,Node.js的出現打破了這個局面,以至出現了「大前端」的發展趨勢。
Node.js中間層+瀏覽器是目前實現「大前端」的基本模式,前端工程師掌握着與用戶相關的全部資源,可以全面地掌握開發進度以及實現更合理的先後端分離方案。這種模式讓前端工程師突破瀏覽器的瓶頸,邁向Web應用層面,這也是將來前端發展的主流趨勢。
不管是專一於瀏覽器,仍是兼顧了Node.js中間層,前端工程師的利劍始終指向的是面向瀏覽器的Web領域,前端工程化所提供的是一種服務,服務對象是不斷參與到項目迭代過程當中的前端開發人員,服務的內容涉及到開發、構建、部署等各個環節。
前端工程師在將來的定位必然會發生變化,可是前端工程化惟一不變的原則是始終之前端開發爲中心,前端工程化沒有統一的行業標準,也沒有固定的形態,更沒有最合理的方案,只要前端工程師的定位還在不斷的變化,前端工程化的進程將會一直持續下去。
想要學習web前端的同窗,能夠參考千鋒成都web前端培訓班提供的學習大綱;