前端工程本質(zhì)上是軟件工程的一種。軟件工程化關(guān)注的是性能、穩(wěn)定性、可用性、可維護性等方面,注重基本的開發(fā)效率、運行效率的同時,思考維護效率。一切以這些為目標的工作都是'前端工程化'。工程化是一種思想而不是某種技術(shù)。舉例說明: 要蓋一棟大樓,假如我們不進行工程化的考量那就是一上來掂起瓦刀、磚塊就開干,直到把大樓壘起來,這樣做往往意味著中間會出現(xiàn)錯誤,要推倒重來或是蓋好以后結(jié)構(gòu)有問題但又不知道出現(xiàn)在哪誰的責任甚至會在某一天轟然倒塌,那我們?nèi)绻霉こ袒乃枷肴プ?,就會先畫圖紙、確定結(jié)構(gòu)、確定用料和預算以及工期,另外需要用到什么工種多少人等等,我們會先打地基再建框架再填充墻體這樣最后建立起來的高樓才是穩(wěn)固的合規(guī)的,什么地方出了問題我們也能找到源頭和負責人。 前端,是一種GUI軟件我們知道前端技術(shù)的主要應用場景并非只是高大上的基礎(chǔ)庫/框架,拽炫酷的宣傳頁面,或者屌炸天的小游戲等這些一兩個文件的小項目,更具商業(yè)價值的則是復雜的Web應用,它們功能完善,界面繁多,為用戶提供了完整的產(chǎn)品體驗。(可能是新聞聚合網(wǎng)站,可能是在線購物平臺,可能是社交網(wǎng)絡,可能是金融信貸應用,可能是音樂互動社區(qū),也可能是視頻上傳與分享平臺……) 從本質(zhì)上講,所有Web應用,都是一種運行在網(wǎng)頁瀏覽器中的軟件,這些軟件的圖形用戶界面(Graphical User Interface,簡稱GUI)即為前端。 如此復雜的Web應用,動輒幾十上百人共同開發(fā)維護,其前端界面通常也頗具規(guī)模,工程量不亞于一般的傳統(tǒng)GUI軟件: ![]() GUI軟件 前端工程化需要考慮哪些因素?1. 模塊化簡單來說,模塊化就是將一個大文件拆分成相互依賴的小文件,再進行統(tǒng)一的拼裝和加載。(方便了多人協(xié)作)。 分而治之是軟件工程中的重要思想,是復雜系統(tǒng)開發(fā)和維護的基石,這點放在前端開發(fā)中同樣適用。模塊化是目前前端最流行的分治手段。
不管你將來是否要復用某段代碼,你都有充分的理由將其分治為一個模塊。
AMD/CommonJS/UMD/ES6 Module等等。 CommonJS的核心思想是把一個文件當做一個模塊,要在哪里使用這個模塊,就在哪里require這個模塊,然后require方法開始加載這個模塊并且執(zhí)行其中的代碼,最后會返回你指定的export對象。 module.export = function() { hello: function() { alert('你好'); }}var a = require('./xxx/a.js');a.hello(); // ==> 彈窗“你好” CommonJS 加載模塊是同步的,所以只有加載完成才能執(zhí)行后面的操作,不能非阻塞的并行加載多個模塊。 AMD(異步模塊定義,Asynchronous Module Definition),特點是可以實現(xiàn)異步加載模塊,等所有模塊都加載并且解釋執(zhí)行完成后,才會執(zhí)行接下來的代碼。
在一些同時需要AMD和CommonJS功能的項目中,你需要使用另一種規(guī)范:Universal Module Definition(通用模塊定義規(guī)范)。UMD創(chuàng)造了一種同時使用兩種規(guī)范的方法,并且也支持全局變量定義。所以UMD的模塊可以同時在客戶端和服務端使用。 幸運的是在JS的最新規(guī)范ECMAScript 6 (ES6)中,引入了模塊功能。 // CommonJS代碼// lib/counter.jsvar counter = 1;function increment() { counter++;}function decrement() { counter--;}module.exports = { counter: counter, increment: increment, decrement: decrement};// src/main.jsvar counter = require('../../lib/counter');counter.increment();console.log(counter.counter); // 1
在less、sass、stylus等預處理器的import/mixin特性支持下實現(xiàn)、css modules。 雖然SASS、LESS、Stylus等預處理器實現(xiàn)了CSS的文件拆分,但沒有解決CSS模塊化的一個重要問題:選擇器的全局污染問題; CSS in JS是徹底拋棄CSS,使用JS或JSON來寫樣式。這種方法很激進,不能利用現(xiàn)有的CSS技術(shù),而且處理偽類等問題比較困難; CSS Modules 原理:使用JS 來管理樣式模塊,它能夠最大化地結(jié)合CSS生態(tài)和JS模塊化能力,通過在每個 class 名后帶一個獨一無二 hash 值,這樣就不有存在全局命名沖突的問題了。 webpack 自帶的 css-loader 組件,自帶了 CSS Modules,通過簡單的配置即可使用。 { test: /\.css$/, loader: 'css?modules&localIdentName=[name]__[local]--[hash:base64:5]'} 2. 組件化前端作為一種GUI軟件,光有JS/CSS的模塊化還不夠,對于UI組件的分治也有著同樣迫切的需求。分治的確是非常重要的工程優(yōu)化手段。 ![]() 前端組件化開發(fā)
由于系統(tǒng)功能被分治到獨立的模塊或組件中,粒度比較精細,組織形式松散,開發(fā)者之間不會產(chǎn)生開發(fā)時序的依賴,大幅提升并行的開發(fā)效率,理論上允許隨時加入新成員認領(lǐng)組件開發(fā)或維護工作,也更容易支持多個團隊共同維護一個大型站點的開發(fā)。 3. “智能”加載靜態(tài)資源(性能優(yōu)化)模塊化/組件化開發(fā)之后,我們最終要解決的,就是模塊/組件加載的技術(shù)問題。然而前端與客戶端GUI軟件有一個很大的不同:前端是一種遠程部署,運行時增量下載的GUI軟件。 如果用戶第一次訪問頁面就強制其加載全站靜態(tài)資源再展示,相信會有很多用戶因為失去耐心而流失。根據(jù)“增量”的原則,我們應該精心規(guī)劃每個頁面的資源加載策略,使得用戶無論訪問哪個頁面都能按需加載頁面所需資源,沒訪問過的無需加載,訪問過的可以緩存復用,最終帶來流暢的應用體驗。 這正是Web應用“免安裝”的魅力所在。 由“增量”原則引申出的前端優(yōu)化技巧幾乎成為了性能優(yōu)化的核心。
還有復雜的BigRender、BigPipe、Quickling、PageCache等技術(shù)。
資源表是一份數(shù)據(jù)文件(比如JSON),是項目中所有靜態(tài)資源(主要是JS和CSS)的構(gòu)建信息記錄,通過構(gòu)建工具掃描項目源碼生成,是一種k-v結(jié)構(gòu)的數(shù)據(jù),以每個資源的id為key,記錄了資源的類別、部署路徑、依賴關(guān)系、打包合并等內(nèi)容。
在查表的時候,如果一個靜態(tài)資源有pkg字段(用來記錄web應用中一個頁面加載過的靜態(tài)資源,當下個頁面用到這個資源就無需加載了,有效利用緩存),那么就去加載pkg字段所指向的打包文件,否則加載資源本身。 4. 規(guī)范化規(guī)范化其實是工程化中很重要的一個部分,項目初期規(guī)范制定的好壞會直接影響到后期的開發(fā)質(zhì)量。
5. 自動化任何簡單機械的重復勞動都應該讓機器去完成。
|
|