編譯
工程化是一個編譯和打包的過程。
首先,什么是編譯?
(資料圖)
舉個例子,當我們需要執行一個java文件。
在前端工程化以前,作為一門解釋型語言,JavaScript是不需要像Java這樣經過編譯這個過程,它可以在瀏覽器中直接運行。
那么,為什么現在不這么做了?
瀏覽器兼容性問題
開發人員編寫的不再是純粹的JavaScript
解釋第一點:
事實上,JS的版本每年都在升級,tc39每年都會收集意見稿對JS標準做出一些改動,增加一些特性,刪除一些特性,其中最著名的版本就是ES2015(ES6)。
但JS的迭代跟Java的迭代不同,這個過程并不由開發者決定。
在Java中,只要開發者不主動升級JDK,那么Java新版本的改動就不會影響到開發者的代碼,代碼的運行結果也始終不會脫離期望。
但在JS中,這個過程由瀏覽器廠商和用戶決定,開發者并不能知道自己的代碼會被作為什么版本的JS來執行。
假如,開發者為了方便開發,在自己的代碼中使用了ES2022的新特性,但用戶使用的是廠商在2020年發布的瀏覽器,那么,你費盡心血編寫的代碼,將不能得到所期望的結果。
而且,瀏覽器廠家并不是只有Google,瀏覽器內核也并不是只有blink,不同內核,甚至相同內核不同版本的瀏覽器對JavaScript的執行能力也不一致。
我們需要一個工具,來將兼容性不那么良好的高版本JS,編譯成兼容性相對更加優秀的低版本JS。
這樣的話,即可以在開發中使用新特性來簡化開發,也能確保在低版本瀏覽器中能夠被正確地執行。
它就是babel。
解釋第二點:
所有的網頁歸根結底由HTML(結構)、CSS(樣式)、JS(交互)組成。
但直接編寫上述三種文件來滿足現代網頁的開發需求是難以實現的,主要問題在于:
現代網頁結構異常復雜,動則成千上萬個dom,難以拆分
樣式表命名空間復雜,權限比重不清
操作dom的api并不是那么易于使用,且弱類型的JS難以維護
為了解決上述問題才有了React、Vue、Angluar、Svelet、Solid等前端框架。而這些框架為了解決上述問題提出了自己的代碼格式:react的jsx、vue的sfc,它們是JS又不是JS。
為了解決JS弱類型難以維護的問題,Microsoft提出了TypeScript,同樣的,.ts是JS又不是JS。
目錄結構
為了在不同框架下保持統一,前端項目在目錄結構上有一些不成文的約定
根目錄下:
public目錄,這個目錄中的文件會保持原樣輸出到打包好的代碼中
dist目錄,打包好的代碼默認輸出到這個目錄出,若不存在則構建工具會自動生成它
src目錄,所有源代碼(除index.html外),都應該存放在此目錄中
src目錄下:
assets目錄,存放圖片、字體、樣式表等網頁需要引用的靜態資源。注意,資源雖然是靜態的,但仍會在打包過程中被編譯,構建工具會使用一段hash重命名這些資源,資源的路徑也會被改變。
api目錄,存放發送網絡請求相關代碼,比如封裝axios,react-query部分的代碼。
components目錄:存放公共組件,多次被引用才算公共組件,只被一個位置引用的組件不應該出現在這里
hooks目錄:存放公共hook。注意,hook對項目框架是有依賴的,并不能跨平臺使用。
pages目錄:存放網頁代碼,每個網頁都應該是一個目錄。
routes目錄:存放路由表,及路由配置代碼。
stores目錄:存放全局狀態機,比如pinia、redux相關代碼。
types目錄:存放.d.ts聲明文件。
utils目錄:存放公共函數,不同于公共hook。公共函數不對框架有依賴,這部分代碼應當是跨平臺的。
入口文件:整個應用程序的入口文件
根組件:框架的根節點
路徑別名
在引入一個自定義模塊,或是使用靜態資源文件的時候,都會需要使用到路徑。
引用資源時,相對路徑不應當被濫用。如下:
使用路徑別名,改變上面這種丑陋的引用方式。
有些構建工具默認配置了上述約定,而有些則需要手動配置。
配置路徑別名(vite舉例)
打包
正如前面提到的,所有的網頁最終給到用戶的一定是HTML、CSS、JS。
構建工具會將我們編寫好的.ts、.tsx、.jsx、.vue、.scss、.less等文件編譯成.js和.css。
需要注意:
有些打包工具會將有引用關系的模塊直接編譯為單個.js。這往往會造成編譯出的.js過大,從而影響用戶打開網頁的速度。
對于體積較大的npm包,最好在打包時進行分包。
必要時可以打包生成gzip,用以提高網頁的加載速度。(需要nginx開啟支持)
標簽: