歡迎關注個人我的博客分享一些前端技術、面試題、面試技巧等css
Web 前端開發這幾年發展很是迅速,很是多的開發框架和構建工具的涌現,敬愛的前端攻城獅,可能你昨天還在用的工具、插件,到了今天可能就過期了。到了今天,外面的世界已經變了。html
當你在遇到一個 Bug 須要修復時,沒有比工程化推廣更迫切的事情了前端
工具和語言雖然差別大,可是解決的都是類似的問題,大概有如下幾點node
所謂工程化,能夠簡單認爲是將框架的職責拓寬再拓寬,主旨是幫業務團隊更好的完成需求,工程化會預測一些常碰到的問題,將之扼殺在搖籃,而這種路徑是可重用的,是具備可持續性。webpack
好比第一個優化去除冗餘,是在屢次去除冗餘代碼,思考冗餘出現的緣由而最終思考得出一個避免冗餘的方案。git
說到構建工具,咱們每每會在前面加上(自動化)三個字,由於構建工具就是用來讓咱們再也不作機械重複的事情,解放咱們的雙手。github
要完成前端工程化,少不了工程構建工具,requireJS
與grunt
的出現,改變了業界前端代碼的編寫習慣,同時他們也是推進前端工程化的一個基礎web
requireJS
是一偉大的模塊加載器,他的出現讓 JavaScript 製做多人維護的大型項目成爲可能。 grunt
是一款 JavaScript 構建工具,主要完成編譯、壓縮、合併等一系列工做,後續又出了Gulp
、WebPack
等構建工具。面試
WebPack
具備Gulp
、grunt
對於靜態資源自動化構建的能力,但更重要的是,WebPack
彌補了requireJS
在模塊化方面的缺陷,同時兼容 AMD 與 CMD 的模塊加載規範,具備更強大的 JS 模塊化功能。npm
開發模式比較簡單,主要就是監聽文件變化,自動進行打包、合併的操做
參考咱們得技術棧與需求,咱們的靜態文件都要發佈到 cdn 上,並且必須有 md5 版本號,方便快速發佈(cdn 更新極其緩慢,因此更新必須使用新的文件名)
生產模式主要增長了文件壓縮、文件 md5 名修改、替換 HTML 等操做
這樣的好處是上線很是方便,一個命令便可更新線上,並且不存在緩存問題
CDN 是構建在網絡之上的內容分發網絡,依靠部署在各地的邊緣服務器,經過中心平臺的負載均衡、內容分發、調度等功能模塊,使用戶就近獲取所需內容,下降網絡擁塞,提升用戶訪問響應速度和命中率。CDN 的關鍵技術主要有內容存儲和分發技術。
CDN 的基本原理是普遍採用各類緩存服務器,將這些緩存服務器分佈到用戶訪問相對集中的地區或網絡中,在用戶訪問網站時,利用全局負載技術將用戶的訪問指向距離最近的工做正常的緩存服務器上,由緩存服務器直接響應用戶請求。
CDN 網絡是在用戶和服務器之間增長 Cache 層,如何將用戶的請求引導到 Cache 上得到源服務器的數據,主要是經過接管 DNS 實現,這就是 CDN 的最基本的原理
www.web.com
這個域名,瀏覽器第一次發現本地沒有 dns 緩存,則向網站的 dns 服務器請求wwww.web.51cdn.com
,請求指向了 CDN 網絡中的智能 DNS 負載均衡系統前端須要模塊化:JS 模塊化不只僅是爲了提升代碼複用性,多人協做開發項目,更是爲了讓資源文件更合理的進行緩存
當在 WebPack 處理後,輸出的靜態文件只剩下 JS、png、Css、jpg
source map
,即便打包在一塊兒依舊方便調試任何靜態資源均可以視做模塊,而後模塊之間也能夠相互依賴,經過 WebPack 對模塊進行處理後,能夠打包咱們想要的靜態資源
新建 WebPackDemo 文件夾,使用npm init
命令生成package.json
文件。
使用npm install webpack -D
安裝 webpack
webpack.config.js
文件,編寫配置文件
項目結構
webpack-demo
|-- node_modules
|-- src
|-- index.js
| index.html
| package.json
| webpack.config.js
複製代碼
npx webpack
會在項目文件夾中生成一個 out 文件夾,裏邊會有編譯後的 index.js。
loader 意義 這些加載器主要作一些預處理的工做,好比 less 等,這裏咱們以 css 和 babel 編譯 E2015 爲例
安裝 loader 咱們第一步就是先要安裝好各個須要使用的 loader。 運行如下命令進行安裝npm install babel-loader babel babel-core css-loader style-loader -D
添加 css 文件,在 js 文件中引用以後使用 WebPack 打包
若是編譯過程當中出現報錯 Error: Cannot find module '@babel/core' babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'. 使用命令
npm install babel-loader@7
編譯完成後查看index.html
,查看源碼後發現head
標籤裏多出了style
標籤,裏面正是咱們想要的樣式。
咱們以前也說過,WebPack 對於靜態資源來講,也是看作模塊來加載的,Css 咱們是已經看過了。那麼圖片是怎麼做爲模塊打包加載進來的呢?這裏咱們能夠想到,圖片咱們是url-loader
加載的,咱們在 Css 文件裏的 url 屬性,其實就是一種封裝處理過的 require 操做,固然咱們還有一種方式就是直接對元素的 src 屬性進行 require 賦值。
npm install url-loader file-loader
複製代碼
div {
background-image: url("./1.jpg");
}
複製代碼
let img = document.createElement("img");
img.src = require("./image/xxx.png");
document.body.appendChild(img);
複製代碼
上述兩種方法都會對符合要求的圖片進行處理。而要求就是在 url-loader 後面經過 query 參數的方式實現的,這裏就是說只有不大於8kb的圖片纔會打包處理成 Base64 格式的圖片。
{
test: /.jpg|png|gif|svg$/,
use: ['url-loader?limit=8192&name=./[name].[ext]']
}
複製代碼
publicPath
是像圖片這種靜態資源打包後的根路徑,當瀏覽器須要引用輸入靜態資源文件時,這個配置項指定輸入文件的公共 URL 地址。在 loader 中它被嵌入到 script 或者 link 標籤或者對靜態資源的引用裏。當文件的 href 或者 url()與它在磁盤上的路徑不一致時就應當用 publicPath,當你想定義一些或者全部文件放在不一樣的主機或 CDN 上時會有用。
編譯後實現效果
WebPack 不只適用於 SPA 開發,對於多頁面,多站點,WebPack 支持的很好,經過更改配置文件爲多入口
output 設置裏面[name]
表明 entry
的每個鍵值,所以運行 WebPack 時候會輸出對應多個文件,out/page1.js
,out/page2.js
,在index.html
和index2.html
兩個頁面分別引用。
代碼壓縮插件:uglifyjs-webpack-plugin
插件下載 npm install uglifyjs-webpack-plugin --save-dev
插件使用
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
optimization: {
minimizer: [new UglifyJsPlugin()]
}
};
複製代碼
具體配置請訪問:github.com/webpack-con…
**頁面分離:**前端工程一項就是減小 http 請求,這表示須要把多個 js 合併成一個,可是,單個 JS 文件過大會影響瀏覽器下載文件的速度,因爲如今瀏覽器併發 http 請求多達 6 個,能夠利用這個特性,將複用第三方資源庫奮力加載。
模塊分離插件:SplitChunksPlugin
Originally, chunks (and modules imported inside them) were connected by a parent-child relationship in the internal webpack graph. The CommonsChunkPlugin was used to avoid duplicated dependencies across them, but further optimizations where not possible
Since version 4 the CommonsChunkPlugin was removed in favor of optimization.splitChunks and optimization.runtimeChunk options.
經過將公共模塊拆出來,最終合成的文件可以在最開始的時候加載一次,便存起來到緩存中供後續使用。
咱們須要在webpack.config.js
文件中添加下面的代碼
splitChunks: {
chunks: "async", // initial、async和all
minSize: 30000, // 造成一個新代碼塊最小的體積 默認是 3000
minChunks: 1, // 在分割以前,這個代碼塊最小應該被引用的次數
maxAsyncRequests: 5, // 按需加載時候最大的並行請求數。
maxInitialRequests: 3, // 一個入口最大的並行請求數
automaticNameDelimiter: '~',
name: true, // 打包的chunks的名字 字符串或者函數(函數能夠根據條件自定義名字)
cacheGroups: { // 這裏開始設置緩存的 chunks
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
複製代碼
具體配置請訪問:www.webpackjs.com/plugins/spl…
獨立出Css樣式,若是咱們但願樣式經過<link>
引入,而不是放在<style>
標籤中,即便這樣作會多一個請求。
安裝 npm install mini-css-extract-plugin --save-dev
爲了區分開<link>
連接和用<style>
,咱們這裏以Css後綴結尾的模塊用插件。
Use webpack with a development server that provides live reloading. This should be used for development only.
安裝:npm install webpack-dev-server --save-dev
WebPack 根據 webPack.config.js
中的入口文件,在入口文件裏識別模塊依賴,無論這裏的模塊依賴是用CommonJS寫的,仍是用 ES6 Module 規範寫的,WebPack會自動進行分析,並經過轉換、編譯代碼、打包成最終的文件。(最終的文件是基於Webpack本身實現的ES5代碼,因此能夠跑在瀏覽器)
但願對讀完本文的你有幫助、有啓發,若是有不足之處,歡迎批評指正交流!
歡迎關注個人我的博客分享一些前端技術、面試題、面試技巧等
辛苦整理良久,還望手動點贊鼓勵~
'摘抄'不是單純的「粘貼->複製」,而是眼到,手到,心到的一字一句敲打下來。
博客聲明:全部轉載的文章、圖片僅用於做者本人收藏學習目的,被要求或認爲適當時,將標註署名與來源。若不肯某一做品被轉用,請及時通知本站,本站將予以及時刪除。