Webpack4 那點兒東西

張淼發表於2018-03-31

What

近幾年,構建對於前端開發來說是一個很重要的名詞,它給前端開發注入了很大的活力,解放了很多生產力。而webpack在前端專案中起了不可小覷的作用,它可以將我們所用的各種瀏覽器不認識的程式碼比如es6,es7,sass,less等轉換為瀏覽器認識的語言,可以對檔案進行壓縮合並,程式碼進行分割,模組合併。。。

Why

昨天翻看我司的專案,雖然各個專案用的都是webpack,但是哪個版本的都有,webpack1,webpack2,webpack3應有具有。很多外掛隨著版本的升級是會有問題或者是不能再用的,因此對於webpack的配置還是要不斷更新,不斷學習的。所以我覺得有必要總結一下,正巧webpack於2018年2月25日正式釋出v4.0.0版本,代號legato,所以本文基於最新的webpack4.0進行講解常規用法。不過第一步,我覺得還是有必要講下webpack4的Update Log中比較重要的幾條。

Update

  1. 環境支援: 官方宣佈不再支援Node 4, Node 6,使用的是v8 5.0版本,支援93%的ES6語法。因為webpack4使用了很多JS新的語法,它們在新版本的 v8 裡經過了優化。
  2. 0配置 受Parcel打包工具啟發,儘可能的讓開發者執行專案的成本變低。webpack4不再強制需要 webpack.config.js 作為打包的入口配置檔案了,它預設的入口為’./src/’和預設出口’./dist’,這對於小專案來說確實是一件不錯的事情。
  3. Mode webpack需要設定mode屬性,可選 development 或 production。
"scripts": { 
"dev": "webpack --mode development", "build": "webpack --mode production"
}複製程式碼

development模式特性:

a.瀏覽器除錯工具b.註釋、開發階段的詳細錯誤日誌和提示c.快速和優化的增量構建機制複製程式碼

production模式特性:

a.開啟所有的優化程式碼b.更小的bundle大小c.去除掉只在開發階段執行的程式碼d.Scope hoisting和Tree-shaking複製程式碼
  1. 外掛變化 webpack4刪除了CommonsChunkPlugin外掛,它使用內建API optimization.splitChunks 和 optimization.runtimeChunk,即webpack會預設為你生成共享的程式碼塊。
  2. 開箱即用WebAssembly(筆者暫時未使用)

Use

  1. 配置項
  • Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。
  • Module:模組,在 Webpack 裡一切皆模組,一個模組對應著一個檔案。Webpack 會從配置的 Entry 開始遞迴找出所有依賴的模組。
  • Chunk:程式碼塊,一個 Chunk 由多個模組組合而成,用於程式碼合併與分割。
  • Loader:模組轉換器,用於把模組原內容按照需求轉換成新內容。
  • Plugin:擴充套件外掛,在 Webpack 構建流程中的特定時機注入擴充套件邏輯來改變構建結果或做你想要的事情。
  • Output:輸出結果,在 Webpack 經過一系列處理並得出最終想要的程式碼後輸出結果。
  1. 啟動命令執行webpack –mode development 會去全域性找webpack包,如果沒有安裝的話會告訴你 bash: webapck: command not found。解決方案:
  • 使用npx 即 npx webpack development( npm 5.2.0版本支援的一個工具)詳細介紹
  • 在package.json中配置scripts
"scripts": { 
"build": "webpack --mode development", "dev": "webpack-dev-server --open --mode development"
},複製程式碼
  1. 上述在scripts我們已經配好了webpack-dev-server,它是開發時的一個伺服器,把打包的檔案全部放入記憶體中,可以熱更新,熱替換等方便我們開發。
npm i webpack-dev-server ---save-dev複製程式碼

完整簡單配置:

const path = require('path');
module.exports = {
entry:path.resolve(__dirname,'src','index.js'), output:{
path: path.resolve(__dirname,'dist'), filename:'bundle.js'
}, devServer:{//配置此靜態檔案伺服器,可以用來預覽打包後專案 contentBase:path.resolve(__dirname,'dist'),//開發服務執行時的檔案根目錄 host:'localhost',//主機地址 port:9090,//埠號 compress:true//開發伺服器是否啟動gzip等壓縮
}
}複製程式碼

4.css檔案處理 css-loader用來解析處理CSS檔案中的url路徑,要把CSS檔案變成一個模組,style-loader 可以把CSS檔案變成style標籤插入head中。執行順序從右向左依次執行,先走css-loader,再走style-loader.

npm i style-loader css-loader ---save-devrules: [            { 
test:/\.css$/, loader:['style-loader','css-loader']
} ]複製程式碼

5.產出html

npm i html-webpack-plugin ---save-devplugins:[        new HtmlWebpackPlugin({ 
template: path.resolve(__dirname,'src','index.html'),//模板 filename:'index.html', hash:true,//防止快取 minify:{
removeAttributeQuotes:true//壓縮 去掉引號
}
})],複製程式碼

6.提取css檔案為單獨檔案,不是像上面直接打包進入js中,注意extract-text-webpack-plugin 必須下載next版本 不然不支援webpack4

npm install --save-dev extract-text-webpack-plugin@next rules: [            { 
test:/\.css$/, // loader:['style-loader','css-loader'] use:ExtractTextWebapckPlugin.extract({
use:'css-loader'
})//不再需要style-loader
} ]new ExtractTextWebapckPlugin('css/index.css')複製程式碼
  1. sass less 檔案處理
npm i less less-loader ---save-devnpm i node-saas sass-loader ---save-devconst lessExtract = new ExtractTextWebapckPlugin('css/less.css');
const sassExtract = new ExtractTextWebapckPlugin('css/sass.css');
{
test:/\.less$/, use:lessExtract.extract({
use: ['css-loader','less-loader']
})
},{
test:/\.scss$/, use: sassExtract.extract({
use:['css-loader','sass-loader']
})
}複製程式碼
  1. babel轉換js
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 --save-dev{ 
test: /\.js/, use: {
loader: 'babel-loader', query: {
presets: ["env", "stage-0"]
}
}複製程式碼
  1. 常用的三種載入圖片的方式
  • css中引入
body{ 
color: red;
background: url(./images/002.jpg) no-repeat;

}複製程式碼
  • js動態引入
let imgSrc = require('./images/002.jpg');
let img = new Image();
img.src = imgSrc;
document.body.appendChild(img);
複製程式碼
  • html img標籤
  <
img src="./images/002.jpg" alt="">
複製程式碼

前兩種 使用 file-loader( 解決CSS等檔案中的引入圖片路徑問題) url-loader(當圖片較小的時候會把圖片BASE64編碼,大於配置的limit引數的時候還是使用file-loader 進行拷貝)

npm i file-loader url-loader --save-dev{test:/\.(jpg|png|gif|svg)$/,use:'url-loader',include:path.join(__dirname,'./src'),exclude:/node_modules/
}複製程式碼

第三種使用html-withimg-loader進行處理

npm i html-withimg-loader --save-dev{ 
test:/\.(html|htm)$/, use:'html-withimg-loader'
}複製程式碼
  1. 多入口問題陣列的模式並不是多入口,一下入口最終只生成一個js
entry: [path.resolve(__dirname, 'src', 'index.js'),path.resolve(__dirname, 'src', 'base.js')],複製程式碼

多入口的正確寫法是物件的形式,以下入口會產出兩個js檔案

entry:{ 
index:'./src/index.js', base:'./src/base.js'
},複製程式碼

多入口對應的html載入模組用chunk區分

 new HtmlWebpackPlugin({ 
template: path.resolve(__dirname,'src','index.html'), filename:'index.html', chunks:['index'], hash:true,//防止快取 minify:{
removeAttributeQuotes:true//壓縮 去掉引號
}
}),new HtmlWebpackPlugin({
template: path.resolve(__dirname,'src','index.html'), filename:'base.html', chunks:['base'], hash:true,//防止快取 minify:{
removeAttributeQuotes:true//壓縮 去掉引號
}
}),複製程式碼
  1. 加入兩個檔案都需要引入一個第三方庫,比如lodash,這時候我們再每個模組內部都需要引入一下,因此打包的時候每個入庫都會把lodash打包進去,檔案變得很大,這時候我們可以把lodash變成一個入口檔案,然後通過webpack.ProvidePlugin暴露變數,在html中chunk中引用,具體如下:
entry:{ 
index:'./src/index.js', base:'./src/base.js', vendor:'lodash'
} new webpack.ProvidePlugin({
_:'lodash'
})new HtmlWebpackPlugin({
template: path.resolve(__dirname,'src','index.html'), filename:'base.html', chunks:['base','vendor'], hash:true,//防止快取 minify:{
removeAttributeQuotes:true//壓縮 去掉引號
}
}),複製程式碼

我們也可以通過expose-loader向全域性暴露一個物件

let _=require('expose-loader?_!lodash');
複製程式碼
  1. watch監聽檔案打包變化,當檔案變化時自動打包
watch: true,watchOptions: { 
ignored: /node_modules/, //忽略不用監聽變更的目錄 aggregateTimeout: 500, //防止重複儲存頻繁重新編譯,500毫米內重複儲存不打包 poll:1000 //每秒詢問的檔案變更的次數
},複製程式碼
  1. resolve解析(比較常用,可以不寫檔案字尾名)
resolve:{ 
extensions: ["",".js",".css",".json"]
},複製程式碼

14.壓縮js,讓輸出的JS檔案體積更小、載入更快、流量更省,還有混淆程式碼的加密功能

npm i uglifyjs-webpack-plugin --save-dev直接new一下即可new UglifyjsWebpackPlugin()複製程式碼

小結

常見的基本用法大概就總結了這麼多,有興趣可以接著閱讀Webpack4優化之路

來源:https://juejin.im/post/5abef5e96fb9a028e33b9035

相關文章