webpack.config.js
webpack 開箱即用,可以無需使用任何組態檔,然而,webpack 會假定專案的入口起點為 src/index.js,然后會在 dist/main.js 輸出結果,并且在生產環境開啟壓縮和優化,
通常你的專案還需要繼續擴展此能力,為此你可以在專案根目錄下創建一個 webpack.config.js 檔案,然后 webpack 會自動使用它,
webpack.config.js是webpack的組態檔, 作用是:指示 webpack 干哪些活(當你運行 webpack 指令時,會加載里面的配置)
所有構建工具都是基于nodejs平臺運行的~模塊化默認采用commonjs,
下面開始介紹webpack的這個組態檔
創建組態檔
1. 創建檔案 webpack.config.js
2. 配置內容如下
const { resolve } = require('path'); // node 內置核心模塊,用來處理路徑問題,
module.exports = {
entry: './src/js/index.js', // 入口檔案
output: { // 輸出配置
filename: './built.js', // 輸出檔案名
path: resolve(__dirname, 'build/js') // 輸出檔案路徑配置
},
mode: 'development' //開發環境
};
如何打包樣式資源以及loader執行順序是什么
打包 CSS 資源
1. 下載安裝 loader 包
npm i css-loader style-loader less-loader less -D
2. 修改組態檔
/*
webpack.config.js webpack的組態檔
作用: 指示 webpack 干哪些活(當你運行 webpack 指令時,會加載里面的配置)
所有構建工具都是基于nodejs平臺運行的~模塊化默認采用commonjs,
*/
// resolve用來拼接絕對路徑的方法
const { resolve } = require('path');
module.exports = {
// webpack配置
// 入口起點
entry: './src/index.js',
// 輸出
output: {
// 輸出檔案名
filename: 'built.js',
// 輸出路徑
// __dirname nodejs的變數,代表當前檔案的目錄絕對路徑
path: resolve(__dirname, 'build')
},
// loader的配置
module: {
rules: [
// 詳細loader配置
// 不同檔案必須配置不同loader處理
{
// 匹配哪些檔案
test: /\.css$/,
// 使用哪些loader進行處理
use: [
// use陣列中loader執行順序:從右到左,從下到上 依次執行
// 創建style標簽,將js中的樣式資源插入進行,添加到head中生效
'style-loader',
// 將css檔案變成commonjs模塊加載js中,里面內容是樣式字串
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
// 將less檔案編譯成css檔案
// 需要下載 less-loader和less
'less-loader'
]
}
]
},
// plugins的配置
plugins: [
// 詳細plugins的配置
],
// 模式
mode: 'development', // 開發模式
// mode: 'production'
}
模塊loader可以鏈式呼叫,鏈中的每個loader都將對資源進行轉換,鏈會逆序執行,第一個loader將其結果(被轉換后的資源)傳遞給下一個loader,依此類推,最后,webpack期望鏈中的最后的loader 回傳 JavaScript,
應保證 loader 的先后順序:‘style-loader’ 在前,而 ‘css-loader’ 在后,如果不遵守此約定,webpack 可能會拋出錯誤,
不同檔案必須配置不同loader處理
css檔案要用style-loader和css-loader
less檔案要用less-loader,style-loader和css-loader
具體這三個loder的作用見上面代碼注釋,
loader執行順序(非常重要,切記!!!):
use陣列中loader執行順序:從右到左,從下到上 依次執行
其實所謂的從下到上就是把陣列里的每個元素換行展示了,本質還是陣列從右至左,
如何打包html資源
打包html資源需要用到html-webpack-plugin這個插件,下載安裝 plugin 包
npm install --save-dev html-webpack-plugin
實體檔案目錄:

和loader使用的一個區別是,插件plugin下載后需要引入后才能使用:
// 引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
默認配置:
/*
loader: 1. 下載 2. 使用(配置loader)
plugins: 1. 下載 2. 引入 3. 使用
*/
const { resolve } = require('path');
// 引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
]
},
plugins: [
// plugins的配置
// html-webpack-plugin
// 功能:默認會創建一個空的HTML,自動引入打包輸出的所有資源(JS/CSS)
new HtmlWebpackPlugin()
],
mode: 'development'
};
html-webpack-plugin插件的功能:默認會創建一個空的HTML,自動引入打包輸出的所有資源(JS/CSS)

實際開發中我們的需求:需要有結構的HTML檔案
我們可以通過對HtmlWebpackPlugin添加配置選項template,添加目標html檔案的路徑即可,具體配置如下:
/*
loader: 1. 下載 2. 使用(配置loader)
plugins: 1. 下載 2. 引入 3. 使用
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
]
},
plugins: [
// plugins的配置
// html-webpack-plugin
// 功能:默認會創建一個空的HTML,自動引入打包輸出的所有資源(JS/CSS)
// 需求:需要有結構的HTML檔案
new HtmlWebpackPlugin({
// 復制 './src/index.html' 檔案,并自動引入打包輸出的所有資源(JS/CSS)
template: './src/index.html'
})
],
mode: 'development'
};
目標html檔案:

打包出來的檔案:

對html-webpack-plugin插件設定template配置屬性的功能:復制 ‘./src/index.html’ 檔案,并自動引入打包輸出的所有資源(JS/CSS)
如何打包圖片資源
為什么需要對webpack做打包圖片的配置?我們先看一個在樣式中引入圖片(background-image)的實體:
實體目錄結構如下:

index.html:

index.js:

index.less:

如果我們不對圖片資源做配置的話,基礎的webpack.config.js配置如下:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多個loader處理用use
use: ['style-loader', 'css-loader', 'less-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
對專案進行打包后,我們發現圖片資源處理不了,在打包圖片的時候是報錯的:



所以我們需要對圖片進行單獨的處理
我們使用url-loader來處理圖片資源,這里需要下載url-loader和file-loade兩個loader:
npm i url-loader file-loade -D
url-loader有相應的優化配置屬性limit,寫在options里,
limit屬性的作用:圖片大小小于指定數值時,就會被base64處理
- 優點:減少請求數量(減輕服務器壓力)
- 缺點:圖片體積會更大(檔案請求速度更慢)
配置如下:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多個loader處理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 問題:默認處理不了html中img圖片
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
// 使用一個loader
// 下載 url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小于8kb,就會被base64處理
// 優點: 減少請求數量(減輕服務器壓力)
// 缺點:圖片體積會更大(檔案請求速度更慢)
limit: 8 * 1024
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
配置完成后再次打包運行:

圖片資源沒有報錯,
這里我們備注一下上面代碼里我們用到的三張圖片資源:
angular.jpg,12kb大小:

react.png,74kb大小:

vue.jpg,4kb大小:

再來看一下輸出的資源:

我們發現打包后的資源輸出了兩張圖片,一張74kb,一張12kb,但我們實際上引入了三張圖片,還有以這樣圖片去哪里呢?
我們看build:



我們發現vue.jpg經過了base64處理,變成了一個非常長的編碼字串,變成了字串的形式,而不會輸出成一張圖片,所以我們輸出的結果就少了一張圖片,這正是前面url-loader做優化配置屬性limit后的效果,
我們打開build檔案下的index.html檔案驗證一下效果:

三張圖片正常顯示
我們檢查一下html結構,可以發現box1盒子背景圖片(vue.jpg)的url是一個base64的地址:

到這里我們處理了樣式里的圖片資源,只是這樣還不夠,因為除了在樣式中引入圖片以外,我們還可能在html中通過<img>標簽的方式引入圖片:<img src="./angular.jpg" alt="angular">

在html中通過<img>標簽的方式引入圖片后,在原有的配置中我們再打包一次,發現沒有報錯,輸出的結果和之前一樣,打開build下的index.html:

img的路徑還是src="./angular.jpg",./是相對路徑,但是相對路徑下沒有angular.jpg這張圖片:

我們打開build下的index.html,發現<img src="./angular.jpg" alt="angular">這張圖片是找不到的:

這是因為上面url-loader的配置有一個問題:默認處理不了html中img圖片
這里我們還要再加一個loader:html-loader,作用是:處理html檔案的img圖片(負責引入img,從而能被url-loader進行處理)
下載html-loader:
npm i html-loader -D
配置:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多個loader處理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 問題:默認處理不了html中img圖片
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
// 使用一個loader
// 下載 url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小于8kb,就會被base64處理
// 優點: 減少請求數量(減輕服務器壓力)
// 缺點:圖片體積會更大(檔案請求速度更慢)
limit: 8 * 1024
}
},
{
test: /\.html$/,
// 處理html檔案的img圖片(負責引入img,從而能被url-loader進行處理)
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
上面的配置打包后發現還是沒有報錯,但是build下的index.html檔案里img的src變成了[object Module]

這是為什么呢?
這是 因為url-loader默認使用es6模塊化決議,而html-loader引入圖片是common.js,url-loader以es6模塊去決議common.js模塊,決議不了,
解決方法:關閉url-loader的es6模塊化,使用commonjs決議
{
// 問題:默認處理不了html中img圖片
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
// 使用一個loader
// 下載 url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小于8kb,就會被base64處理
// 優點: 減少請求數量(減輕服務器壓力)
// 缺點:圖片體積會更大(檔案請求速度更慢)
limit: 8 * 1024,
// 問題:因為url-loader默認使用es6模塊化決議,而html-loader引入圖片是commonjs
// 決議時會出問題:[object Module]
// 解決:關閉url-loader的es6模塊化,使用commonjs決議
esModule: false
}
},
關閉url-loader的es6模塊化,再次打包,沒有報錯
查看build下的index.html檔案

img的src變成[object Module]的問題已經解決,變成了完整的絕對路徑,上面的長字串是根據圖片內容生成的唯一hash值,
打開build下的index.html檔案,html里的圖片顯示正常:

我們發現打包后圖片的名字有點長,這是根據圖片內容生成的唯一hash值:

不想讓圖片名字這么長可以通過url-loader里的name屬性來給圖片進行重命名:name: '[hash:10].[ext]'
- [hash:10]取圖片的hash的前10位
- [ext]取檔案原來擴展名
對圖片資源最終的配置如下:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多個loader處理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 問題:默認處理不了html中img圖片
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
// 使用一個loader
// 下載 url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小于8kb,就會被base64處理
// 優點: 減少請求數量(減輕服務器壓力)
// 缺點:圖片體積會更大(檔案請求速度更慢)
limit: 8 * 1024,
// 問題:因為url-loader默認使用es6模塊化決議,而html-loader引入圖片是commonjs
// 決議時會出問題:[object Module]
// 解決:關閉url-loader的es6模塊化,使用commonjs決議
esModule: false,
// 給圖片進行重命名
// [hash:10]取圖片的hash的前10位
// [ext]取檔案原來擴展名
name: '[hash:10].[ext]'
}
},
{
test: /\.html$/,
// 處理html檔案的img圖片(負責引入img,從而能被url-loader進行處理)
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
打包后的圖片名稱已經變成取圖片的hash的前10位

另外我們還可以發現webpack打包的一個優勢:
上面的例子中html里參考了一次angular.jpg,在樣式檔案里也參考了一次angular.jpg,但打包之后其實只生成了一張angular.jpg的圖片檔案
所以在這里就是當webpack在決議的時候發現我們使用了同一個檔案,它不會重復打包,它只會輸出一次,這也是webpack的一個優勢,它不會重復打包某一個檔案,
如何打包其他資源
什么是其他資源呢?比如說字體圖示icon
字體圖示的特點就是我們不需要做任何處理,只需要原封不動的輸出出去就ok了,這就是其他資源,不需要做優化,也不需要做壓縮啊等等,這類資源統一歸類于其他資源,
我們先下載一個字體圖示,這里使用iconfont圖示,隨便選擇一個,直接點擊下載代碼

下載完之后解壓一下,這里包含了字體圖示的所有配置

我們這里使用font-class 參考

我們新建檔案夾,src/index.html,使用字體圖示看一看效果


再寫一個入口js檔案,index.js,作用就是負責引入字體圖示樣式檔案

iconfont.css檔案里又參考了.eot、.woff、ttf和.svg資源,我們也需要放入專案中,具體看前面的實體專案檔案目錄

打包其他資源我們可以使用exclude排除已經處理過或者不需要處理的資源,然后使用file-loader對其他資源進行處理,一個小的優化就是可以對打包后的檔案名稱做一個縮短優化
具體配置:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他資源(除了html/js/css資源以外的資源)
{
// 排除css/js/html資源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
打包運行專案,字體圖示顯示正常

如何配置devServer
webpack-dev-server具有實時重新加載 (live reloading) 的功能,用來自動化(自動編譯,自動打開瀏覽器,自動重繪瀏覽器~~)
特點:只會在記憶體中編譯打包,不會有任何輸出
啟動devServer指令為:npx webpack-dev-server
webpack devServer啟動gzip壓縮:compress: true
配置如下:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他資源(除了html/js/css資源以外的資源)
{
// 排除css/js/html資源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
// 開發服務器 devServer:用來自動化(自動編譯,自動打開瀏覽器,自動重繪瀏覽器~~)
// 特點:只會在記憶體中編譯打包,不會有任何輸出
// 啟動devServer指令為:npx webpack-dev-server
devServer: {
// 專案構建后路徑
contentBase: resolve(__dirname, 'build'),
// 啟動gzip壓縮
compress: true,
// 埠號
port: 3000,
// 自動打開瀏覽器
open: true
}
};
配置好devServer,啟動devServer,打開瀏覽器,輸入:localhos:3000,這就是我們使用devServer搭建的服務器,這個服務器啟動的專案,
開發環境配置總結——一個完整的開發環境配置
除了之前的配置,我們還要做一些處理,之前撰寫的實體目錄有點亂

我們劃分一下目錄

把原來的路徑修改好后,輸入命令webpack打包專案,看一下輸出結果:

我們發現所有的資源都輸出到一塊了,沒有任何的差別
如果希望打包后的資源和原來的結構一樣的,可以一個一個調
首先讓先js檔案輸出到js的目錄下,要修改output的filename屬性,在built.js前加js/
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
重新構建一下專案,可以發現build下面就多了一個js目錄

圖片資源修改構建路徑要在url-loader中添加outputPath配置屬性:outputPath: 'imgs'
{
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 關閉es6模塊化
esModule: false,
outputPath: 'imgs'
}
},
這樣圖片資源就會構建在build下面的imgs檔案夾下

其他資源修改構建路徑也是添加outputPath配置屬性:outputPath: 'media'
{
// 處理其他資源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media'
}

把build目錄刪掉,重新打包一次,就可以看到清晰的結構

有人可能會問,為什么構建后的資源沒有看到之前寫的css檔案?這是因為css-loader把css檔案打包到js當中了(復習環節),它是跟js檔案融為一體的,所以沒有被單獨打包出去
{
// 匹配哪些檔案
test: /\.css$/,
// 使用哪些loader進行處理
use: [
// use陣列中loader執行順序:從右到左,從下到上 依次執行
// 創建style標簽,將js中的樣式資源插入進行,添加到head中生效
'style-loader',
// 將css檔案變成commonjs模塊加載js中,里面內容是樣式字串
'css-loader'
]
},

完整的開發環境配置:
/*
開發環境配置:能讓代碼運行
運行專案指令:
webpack 會將打包結果輸出出去
npx webpack-dev-server 只會在記憶體中編譯打包,沒有輸出
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
// 處理less資源
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 處理css資源
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 關閉es6模塊化
esModule: false,
outputPath: 'imgs'
}
},
{
// 處理html中img資源
test: /\.html$/,
loader: 'html-loader'
},
{
// 處理其他資源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media'
}
}
]
},
plugins: [
// plugins的配置
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true
}
};
參考
- https://www.bilibili.com/video/BV1e7411j7T5?p=6
- https://webpack.docschina.org/concepts/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295152.html
標籤:其他
上一篇:開發工具--IDEA基礎設定
下一篇:Java集合---->Map介面
