認識
webpack是優秀的前端構建工具,靜態資源打包器,可以根據模塊依賴關系進行靜態資源分析,快速打包生成相對應瀏覽器可以直接識別的靜態資源!
環境
1)node環境
2)vs code編輯器
規約
1)入口檔案:
開始打包第一個檔案稱為入口檔案,通常經過在入口檔案中引入其他資源,形成資源關系樹狀圖,webpack根據依賴關系進行一次處理,
2)chunk代碼塊:
管理webpack內部的打包行程,chunk可以分為“入口”和“子代碼塊”,入口檔案就是一個chunk,默認的webpack打包配置是一個入口檔案是一個chunk,打包生成一個bundle,但是如果出現代碼分割的情況下,有多個chunk打包生成一個bundle,
3)bundle:
通過處理入口檔案中的關系依賴,最后打包輸出成為瀏覽器可以直接識別的靜態資源檔案就是bundle,
安裝webpack環境
1)專案根目錄控制臺執行指令:npm init,生成package.json檔案,npm是新版本node自帶的包管理工具,而package.json相當于清單,記錄依賴庫和專案資訊的檔案,
2)全域安裝webpack指令: npm i webpack webpack-cli -g ,全域安裝是指系統環境中,任何專案檔案夾下都可以使用指令,其中mac電腦首次執行應該是需要管理員權限,sudo npm i webpack webpack-cli -g 如果網速太慢則建議切換為淘寶鏡像源,
3)本地安裝webpcak指令: sudo npm i webpack webpack-cli -D,下載的模塊是注入于本專案下的./node_nodules檔案夾中,不會影響其他專案,起到獨立的作用!
概念核心:
Entry
入口檔案指示,配置wepack以哪個入口檔案進行打包分析等引數,
entry: "./src/main.js",
Output
出口檔案指示,配置webpack打包后的資源bundle輸出資源的路徑及引數,
output: {
filename: "static/js/[name].js",
path: resolve(__dirname, "build"),
},
Loader
webpack本身僅能識別js、json代碼,而Loader的作用就是將CSS、img、字體資源翻譯成為webpack可以識別的資源,可以識別后才可以進行打包處理!loader通過npm安裝依賴之后就可以配置,不用需要引入,
1)Es語法檢查配置:
// eslint語法檢查
{
/**
* js語法所需loader安裝指令:npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import -D
* eslint的js語法檢查是依托于airbnb規則進行檢查,根據package.json下的eslintConfig的配置進行檢測語法,
* airbnb默認是不能認識window等物件,可通過eslintConfig下的env屬性進行屏蔽檢查,可通過eslint-disable-next-line注釋取消下一行的語法檢查,
*/
test: /\.js$/, // 通過正則匹配后綴名為.js的檔案
enforce: "pre", // 設定loader的執行順序,pre(優先)| post(延后),
exclude: /node_modules/, // 排除node_modules目錄下js檔案的語法檢查
loader: "eslint-loader", // 指定eslint-loader執行處理js檔案進行語法檢查
options: {
fix: true, // 配置參、空格、縮進不規范的語法自動進行修復,
},
},
2)處理CSS檔案并兼容:
{
// 處理css檔案的規則所需loader安裝指令:npm i style-loader -D 和 npm i css-loader -D
test: /\.css$/,
// 處理檔案時使用到多個lorder時,執行順序為從下到上,
use: [
// "style-loader", // 處理創建style標簽,將js中處理的資源添加到style標簽中,再添加到頁面head中生效,
{
loader: MiniCssExtractPlugin.loader, // 因為css引入js檔案中,會造成js代碼檔案過大,所以通過MiniCssExtractPlugin建構式自帶loader取代style-loader,作用為將css抽離成為單個檔案通過link標簽引入,
options: {
publicPath: "../../", // 資源引入html檔案時的路徑前綴,因為css檔案以及被單獨抽離至特定目錄下,正確修改才能匹配到css中參考的靜態資源,
},
},
// 翻譯css使webpack能夠識別css樣式語法
"css-loader",
{
loader: "postcss-loader", // 使用postcss進行瀏覽器兼容,使用的方法是在package.json中定義browserslist屬性規則進行瀏覽器兼容性語法補全,
options: {
ident: "postcss",
plugins: () => [require("postcss-preset-env")],
},
},
],
},
3)處理Less檔案:
{
// 處理less檔案的規則所需loader安裝指令:npm i less-loader -D 和 npm i less -D
test: /\.less$/,
use: [
// "style-loader",
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../../",
},
},
"css-loader",
"less-loader",
],
},
4)處理圖片檔案:
{
// 處理圖片檔案的規則安裝指令:cnpm i url-loader file-loader -D
test: /\.(png|jpe?g|gif|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 80 * 1024, // 當圖片小于80kb時采用base64的方式打包,大于則以圖片形式打包,
name: "[hash:10].[ext]", // 每次webpack構建打包會生成一串不重復的hash碼,[hash:10]則是去hash的前十位,[ext]取源檔案的后綴名,
outputPath: "static/img", // 輸出目錄,output定義了輸出目錄為build,此處圖片輸出目錄為build/static/img/XXX檔案,
esModule: false, // 默認使用es6語法決議,html-loader使用的是commonjs語法引入,但2020年09月24日不用關閉url-loader的es6決議方法,
},
},
5)處理html檔案引入的圖片:
{
// 處理html中img等標簽引入的圖片資源所需loader安裝指令:npm i html-loader -D
test: /\.html$/,
loader: "html-loader", // 處理url-loader僅能處理打包圖片而不能處理html中資源的遺留問題,
},
6)處理字體圖示:
{
// 處理引入字體圖示資源所需loader安裝指令:npm install file-loader -D
test: /(\.(ttf|woff|eot)$|iconfont\.svg)/,
loader: "file-loader",
options: {
name: "[hash:10].[ext]",
outputPath: "static/font",
},
},
7)處理JS檔案并兼容:
{
/**
* 處理es6語法轉es5語法和Promise等新增屬性所需的loader安裝指令:npm i babel-loader @babel/preset-env @babel/core @babel/polyfill core-js -D
* 關于解決Promise等新增技術IE舊(垃)版(圾)瀏覽器不能識別的問題:
* 1)入口檔案中首行添加import '@babel/polyfill' 引入模塊,簡單方便,但會引入不必要的兼容配置,造成代碼體積偏大,
* 2)按需加載比較推薦
*/
test: /\.js$/,
exclude: /node_modules/,
use: [
{
/**
* 開啟多行程打包所需loader安裝指令:npm install thread-loader -D
* 可以給每一個規則使用這個loader,但是建議只給js進行,因為js打包花費的時間很多,建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
*/
// ,
loader: "thread-loader", // 建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
options: {
works: 4, // 核數
},
},
{
loader: "babel-loader",
options: {
presets: [
// "@babel/preset-env" // 把下面陣列的注釋掉不會適配Promise等高級技術了,僅僅會轉換let、const、箭頭函式,
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: {
version: 3,
},
// 兼容范圍
targets: {
chrome: "50",
firefox: "50",
ie: "10",
safari: "10",
edge: "18",
},
},
],
],
// 開啟JS代碼快取,當檔案名不變時,瀏覽器強制快取js檔案,導致修改的專案不能實時更新,所以應該在output中輸出檔案名中包含hash值,采用的是[content:10]的根據內容生成hash值的形式,沒有采用hash是因為css在js中引入屬于同一個chunk,輸出時帶有同一個hash值,
cacheDirectory: true,
},
},
],
},
Plugins
插件(plugins)可以讓webpack執行范圍更廣更為復雜的任務,配置打包優化等一下相關的作用功能,使用前需要單獨引入對應的插件,
1)處理html檔案插件:
// 無template屬性時,默認在輸出目錄創建一個空的html檔案,并將打包后的資源引入其中,template指明檔案時,則復制檔案,并引入打包后的資源,
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
collapseWhitespace: true, // 清除空行縮進
removeAttributeQuotes: true, // 清除注釋
},
}),
2)抽離CSS成單獨檔案插件:
// 處理CSS從js檔案中抽離生成獨立檔案
new MiniCssExtractPlugin({
filename: "static/css/app.css", // 檔案輸出目錄
}),
3)壓縮CSS插件:
// Css壓縮插件,需要在package.json中定義sideEffects屬性防止它壓縮去除掉一些css,less等檔案,
new OptimizeCssAssetsWebpackPlugin(),
4)PWA離線訪問技術插件:
// PWA離線快取技術,優化使用體驗,網路斷開后重繪網頁仍能夠加載得到已經快取的資源檔案,依靠service Workers技術,插件執行后生成一個servicework組態檔,需要在入口檔案中注冊,兼容性判斷,
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true, // 幫助servicework快速啟動
skipWaiting: true, // 洗掉舊版本使用最新的serviceworker技術
}),
5)忽略庫并動態引入第三方庫插件:
/**
* dll動態引入單獨庫
* 通過manifest.json檔案中的映射關系,構建打包時進行忽略打包哪些庫,再通過addAssetHtmlWebpackPlugin引入獨立打包的庫,
*/
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, "dll/manifest.json"),
}),
new addAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, "dll/jquery.js"),
}),
Mode
配置webpack的作業方式,其中有開發(development)和生產(production)模式,開發環境配置簡單,能夠使代碼能夠跑在本地即可,生產模式相關復雜,需要處理網站運行上線時的優化等操作,
// mode: "development",
mode: "production", // 設定webpack的作業環境
開發環境優化
HMR熱模塊替換
webpack處于開發環境中時,默認是一個模塊發生改變,全部模塊均會重新加載,為了解決此問題,引入HMR熱模塊替換,資源發生改變時,僅會重新構建打包發生改變的模塊,
1)樣式檔案會自動熱模塊替換,因為style-loader內部實作了這個功能,
2)開啟HMR后html默認是不會自動更新,入口檔案中引入html檔案,但默認是不會對html做HMR,
entry: ["./src/main.js", "./index.html"],
3)js代碼發生改變默認也不可以發生更新,入口檔案中對此進行監聽!
// 判斷是否開啟HRM熱模塊更新,如果開啟則監聽所需的js檔案,則熱模塊替換發生作用,
if (module.hot) {
// 對入口檔案中引入的依賴進行熱部署替換監聽
module.hot.accept("./utils/url.js", () => {
// 一旦監聽到發生改變,立即執行該回呼函式,
getUrl();
});
}
快取方式提高構建速度
1)babel快取:
配置處理js的loader設定cacheDirectory:
true,會強制js快取一定時間,但是會造成開發環境代碼改變后,生產環境下代碼讀取的是快取中的代碼,造成不能實時更新代碼的問題,
2)檔案資源快取:
hash:webpack每次打包構建時會生成一個唯一的hash值,將打包輸出的檔案名字中帶有hash值,則每次改動,重繪均要請求所有資料,不會讀取快取里的資源,造成了js,css快取失效,
chunkhash:根據打包時引入的chunk生成hash值,如果打包資源來自同一個資源檔案件中,hash值就一致,因為css是在js中引入,chunk一致,導致js,變化css也會跟著不會讀取快取,
contenthash: 根據檔案內容生成hash值,不同引入檔案的hash值就不一樣,
output: {
filename: "static/js/[name][contenthash:5].js",
path: resolve(__dirname, "build"),
},
生產環境優化
Tree Shaking樹搖
打包構架去除無用代碼,必須是使用ES6模塊化引入以及必須指定production環境,自動開啟treeshaking模式,減少代碼體積,package.json中配置sideEffects: false所有代碼均開啟樹搖模式,但可能會干掉無辜的css等檔案, 若標記為sideEffects: ["*.css"]時則不會干掉所匹配的檔案,
JS代碼懶加載
通過es6語法引入,延時加載,觸發一定行為才進行請求加載,不是開局就全部加載進來,那樣會增加首次加載的時間,也有著代碼分隔的特性,會被單獨分割成一個單獨檔案,
// 動態js引入,單獨打包生成一個檔案,并給定檔案名,也會有懶加載的現象,添加預加載webpackPrefetch關鍵字,
import(/*webpackChunkName: 'test',webpackPrefetch: true*/ "./test.js")
.then((res) => {
console.log("檔案加載成功", res);
})
.catch((err) => {
console.log("檔案加載失敗", err);
});
預加載
等其他瀏覽器空閑了再偷偷加載,請求到檔案資料了,觸發行為的時候再去讀取快取中的資料,懶加載的方式上添加添加預加載webpackPrefetch關鍵字,
代碼分割code split
1)多入口檔案方式分隔,物件多入口形式,生成多個chunk,構建后形成多個js檔案,用于代碼分隔,
// entry: {
// index: "./src/index.js",
// test: ["./src/test.js"], // 特殊陣列寫法
// },
2)optimization配置分隔,將node_modules的庫單獨分割打包成vendors.js檔案,
optimization: {
splitChunks: {
chunks: "all", // 所有配置均為默認
},
}
3)入口檔案中動態js引入的方式,具有懶加載以及會鏡像代碼分割,
import(/*webpackChunkName: 'add',webpackPrefetch: true*/ "assets/js/add.js")
.then((res) => {
console.log("檔案加載成功", res);
})
.catch((err) => {
console.log("檔案加載失敗", err);
});
PWA漸進式網路開發應用技術(離線訪問)
無網路時,重繪仍然可以訪問到已經加載的網頁,借助了workbox-webpack-plugin插件進行實作,安裝指令:cnpm iworkbox-webpack-plugin -D,且必須運行在服務器中才可以看到結果,
安裝靜態資源服務器
1)npm install serve -g
2)專案根目錄執行指令: serve -s,默認發布打包目錄build下的index.html到靜態資源服務器,
配置插件
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true, // 幫助servicework快速啟動
skipWaiting: true, // 洗掉舊版本使用最新的serviceworker技術
}),
入口檔案作兼容性判斷
// 注冊serviceWork并處理兼容性問題
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("/service-worker.js")
.then((res) => {
// eslint-disable-next-line
console.log("注冊成功", res);
})
.catch((err) => {
// eslint-disable-next-line
console.log("注冊失敗", err);
});
});
}
Source-Map映射技術
構建后代碼到源代碼的有一種映射技術,如果構建代碼出錯了,通過映射關系能找到源代碼的位置,非常利于除錯代碼,但是也會造成代碼被盜用的安全性問題,詳細引數移步webpack.config.js中查看,
/**
* Inline-source-map:行內map檔案不會單獨生成xxx.js.map檔案 直接生成一個map資訊放在打包后的js檔案的最后 構建速度會更快
* Hidden-source-map:默認設定 生成外部的map資訊檔案
* Eval-source-map:同樣也是行內map資訊 在每一個引入的資源后面均生成一個map資訊
* 引數
* source-map:錯誤代碼的準確資訊和源代碼的錯誤位置 并且能夠匯出對應的源代碼
* inline-source-map:列印輸出的檔案位置 可定位到源代碼的位置
* hidden-source-map:列印輸出的是打包后的代碼 可定位到定位打包后的位置 不可以追溯到源代碼的位置
* eva-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置
* nosource-source-map:錯誤和輸出資訊的準確位置,不可追溯到源代碼的行列位置
* cheap-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行位置
* cheap-module-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置 會將webpack配置等資訊添加進來
*/
直接打包構建專案

1)專案根目錄的控制臺執行指令:
webpack ./src/index.js -o ./build/built.js–mode=development,開發模式中打包src下的index.js入口檔案;輸出在build路徑下檔案名為built.js,
2)打包結果分析:
每次打包都會生成不重復且唯一的hash值,打包構建所用時間以及檔案的大小等引數,

組態檔方式構建
專案跟目錄下建立webpack.config,js檔案,當我們控制臺輸入webpack打包指令時,默認會按webpack.config.js中的配置去打包構建,組態檔檔案通過commomjs的方式暴露一個配置物件,這個就不再分析了,具體看webpack.config.js檔案,

webpack.config.js詳細配置
const { resolve } = require("path"); // 引入node.js的一個path路徑模塊,通過解構獲取到一個resolve屬性值,用于獲得當前目錄的絕對路徑,
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 處理html插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 抽離css成單獨檔案插件
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); // 引入壓縮Css代碼插件
const WorkboxWebpackPlugin = require("workbox-webpack-plugin"); // 引入實作PWA離線快取技術插件
const TerserWebpackPlugin = require("terser-webpack-plugin"); // 壓縮js代碼插件
const webpack = require("webpack"); // 引入dll定義屬性插件,通過.json映射檔案實作忽略單獨打包的第三庫,在通過addAssetHtmlWebpackPlug進行單獨引入,
const addAssetHtmlWebpackPlugin = require("add-asset-html-webpack-plugin"); // dll單獨打包庫自動引入html插件
// process.env.NODE_ENV = "production"; // 設定nodejs的行程環境為production生成環境,postcss默認作業于生產環境下,
module.exports = {
entry: "./src/main.js",
/**
* 陣列形式:陣列多入口,構建打包后形成一個chunk,一個js檔案,常用于將html檔案引入,使其具有HMR熱替換功能,
* 物件形式:物件多入口形式,生成多個chunk,構建后形成多個js檔案,用于代碼分隔,
*/
// entry: ["./src/index.js", "./src/test.js"]
// entry: {
// index: "./src/index.js",
// test: ["./src/test.js"], // 特殊陣列寫法
// },
output: {
filename: "static/js/[name].js",
path: resolve(__dirname, "build"),
chunkFilename: "js/[name]~[contenthash:10].js", // 通過懶加Es6懶加載方式和optimization插件進行分割形成的chunk遵循這個命名規則
library: "[name]Lib", // 構建打包向外暴露名,即呼叫名,
libraryTarget: "window", // 系結到window物件中,很多屬性物件,
},
module: {
rules: [
// eslint語法檢查
{
/**
* js語法所需loader安裝指令:npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import -D
* eslint的js語法檢查是依托于airbnb規則進行檢查,根據package.json下的eslintConfig的配置進行檢測語法,
* airbnb默認是不能認識window等物件,可通過eslintConfig下的env屬性進行屏蔽檢查,可通過eslint-disable-next-line注釋取消下一行的語法檢查,
*/
test: /\.js$/, // 通過正則匹配后綴名為.js的檔案
enforce: "pre", // 設定loader的執行順序,pre(優先)| post(延后),
exclude: /node_modules/, // 排除node_modules目錄下js檔案的語法檢查
loader: "eslint-loader", // 指定eslint-loader執行處理js檔案進行語法檢查
options: {
fix: true, // 配置參、空格、縮進不規范的語法自動進行修復,
},
},
{
// 當檔案流到這個物件時,匹配到一個規則之后就不再向下匹配,優化構建打包速度,
oneOf: [
{
// 處理css檔案的規則所需loader安裝指令:npm i style-loader -D 和 npm i css-loader -D
test: /\.css$/,
// 處理檔案時使用到多個lorder時,執行順序為從下到上,
use: [
// "style-loader", // 處理創建style標簽,將js中處理的資源添加到style標簽中,再添加到頁面head中生效,
{
loader: MiniCssExtractPlugin.loader, // 因為css引入js檔案中,會造成js代碼檔案過大,所以通過MiniCssExtractPlugin建構式自帶loader取代style-loader,作用為將css抽離成為單個檔案通過link標簽引入,
options: {
publicPath: "../../", // 資源引入html檔案時的路徑前綴,因為css檔案以及被單獨抽離至特定目錄下,正確修改才能匹配到css中參考的靜態資源,
},
},
// 翻譯css使webpack能夠識別css樣式語法
"css-loader",
{
loader: "postcss-loader", // 使用postcss進行瀏覽器兼容,使用的方法是在package.json中定義browserslist屬性規則進行瀏覽器兼容性語法補全,
options: {
ident: "postcss",
plugins: () => [require("postcss-preset-env")],
},
},
],
},
{
// 處理less檔案的規則所需loader安裝指令:npm i less-loader -D 和 npm i less -D
test: /\.less$/,
use: [
// "style-loader",
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../../",
},
},
"css-loader",
"less-loader",
],
},
{
// 處理圖片檔案的規則安裝指令:cnpm i url-loader file-loader -D
test: /\.(png|jpe?g|gif|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 80 * 1024, // 當圖片小于80kb時采用base64的方式打包,大于則以圖片形式打包,
name: "[hash:10].[ext]", // 每次webpack構建打包會生成一串不重復的hash碼,[hash:10]則是去hash的前十位,[ext]取源檔案的后綴名,
outputPath: "static/img", // 輸出目錄,output定義了輸出目錄為build,此處圖片輸出目錄為build/static/img/XXX檔案,
esModule: false, // 默認使用es6語法決議,html-loader使用的是commonjs語法引入,但2020年09月24日不用關閉url-loader的es6決議方法,
},
},
{
// 處理html中img等標簽引入的圖片資源所需loader安裝指令:npm i html-loader -D
test: /\.html$/,
loader: "html-loader", // 處理url-loader僅能處理打包圖片而不能處理html中資源的遺留問題,
},
{
// 處理引入字體圖示資源所需loader安裝指令:npm install file-loader -D
test: /(\.(ttf|woff|eot)$|iconfont\.svg)/,
loader: "file-loader",
options: {
name: "[hash:10].[ext]",
outputPath: "static/font",
},
},
{
/**
* 處理es6語法轉es5語法和Promise等新增屬性所需的loader安裝指令:npm i babel-loader @babel/preset-env @babel/core @babel/polyfill core-js -D
* 關于解決Promise等新增技術IE舊(垃)版(圾)瀏覽器不能識別的問題:
* 1)入口檔案中首行添加import '@babel/polyfill' 引入模塊,簡單方便,但會引入不必要的兼容配置,造成代碼體積偏大,
* 2)按需加載比較推薦
*/
test: /\.js$/,
exclude: /node_modules/,
use: [
{
/**
* 開啟多行程打包所需loader安裝指令:npm install thread-loader -D
* 可以給每一個規則使用這個loader,但是建議只給js進行,因為js打包花費的時間很多,建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
*/
// ,
loader: "thread-loader", // 建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
options: {
works: 4, // 核數
},
},
{
loader: "babel-loader",
options: {
presets: [
// "@babel/preset-env" // 把下面陣列的注釋掉不會適配Promise等高級技術了,僅僅會轉換let、const、箭頭函式,
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: {
version: 3,
},
// 兼容范圍
targets: {
chrome: "50",
firefox: "50",
ie: "10",
safari: "10",
edge: "18",
},
},
],
],
// 開啟JS代碼快取,當檔案名不變時,瀏覽器強制快取js檔案,導致修改的專案不能實時更新,所以應該在output中輸出檔案名中包含hash值,采用的是[content:10]的根據內容生成hash值的形式,沒有采用hash是因為css在js中引入屬于同一個chunk,輸出時帶有同一個hash值,
cacheDirectory: true,
},
},
],
},
],
},
],
},
// 插件使用需要先引入在new生成實體
plugins: [
// 無template屬性時,默認在輸出目錄創建一個空的html檔案,并將打包后的資源引入其中,template指明檔案時,則復制檔案,并引入打包后的資源,
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
collapseWhitespace: true, // 清除空行縮進
removeAttributeQuotes: true, // 清除注釋
},
}),
// 處理CSS從js檔案中抽離生成獨立檔案
new MiniCssExtractPlugin({
filename: "static/css/app.css", // 檔案輸出目錄
}),
// Css壓縮插件
new OptimizeCssAssetsWebpackPlugin(),
// PWA離線快取技術,優化使用體驗,網路斷開后重繪網頁仍能夠加載得到已經快取的資源檔案,依靠service Workers技術,插件執行后生成一個servicework組態檔,需要在入口檔案中注冊,兼容性判斷,
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true, // 幫助servicework快速啟動
skipWaiting: true, // 洗掉舊版本使用最新的serviceworker技術
}),
/**
* dll動態引入單獨庫
* 通過manifest.json檔案中的映射關系,構建打包時進行忽略打包哪些庫,再通過addAssetHtmlWebpackPlugin引入獨立打包的庫,
*/
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, "dll/manifest.json"),
}),
new addAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, "dll/jquery.js"),
}),
],
// mode: "development",
mode: "production", // 設定webpack的作業環境
// 打包構建忽略打包的庫,并通過手動外部CDN引入,
// externals: {
// jquery: "jquery",
// },
/**
* 安裝指令:npm i webpack-dev-server -D
* 開發服務器自動編譯、自動重繪、自動打開瀏覽器,只會在記憶體中編譯打包,不會輸出代碼,本地安裝啟動指令:npx webpack-dev-server,
*/
devServer: {
contentBase: resolve(__dirname, "build"), // 運行代碼目錄
watchContentBase: true, // 監視contentBase下檔案目錄,發現檔案變化則reload,
watchOptions: {
ignored: /node_modules/, // 忽略檔案
},
compress: true, // 采用gzip壓縮代碼體積會更小
port: 9527,
host: "localhost",
open: true, // 自動打開瀏覽器
hot: true, // 開啟HMR功能,提高開發環境打包的效率,
clientLogLevel: "none", // 不需要開啟webpack啟動日志資訊
quiet: true, // 僅僅顯示基本資訊
overlay: true, // 不要全屏顯示報錯
proxy: {
"/api": {
// 處于5000埠的devserver接收到/api的請求,會將請求代理轉發到3000埠下的服務,
target: "http://localhost:3000/",
// 去掉/api,路徑替換重寫為http://localhost:3000/檔案,
pathRewrite: {
"^/api": "",
},
},
},
},
// 決議模塊
resolve: {
alias: {
assets: resolve(__dirname, "src/assets/"), // 設定路徑別名
},
// extensions: ["js", "css", "vue", "json"], // 引入時可省略的后綴名
modules: ["node_modules"],
},
// 將node_modules里面的庫單獨打包成一個檔案verdor.js,配置項太多了,官網自行查看,
optimization: {
splitChunks: {
chunks: "all", // 所有配置均為默認
},
// 入口檔案打包的主構建檔案(main)需要參考其他的chunk,打包生成后main會存有其他chunk打包的hash值(使用contenthash方式命名),一旦其他chunk發生改動,main也需要重新打包構建,會造成快取失效,此配置將main檔案中記錄其他chunk的hash值打包成為一個單獨的檔案,再將此檔案引入main,達到解耦的效果,
runtimeChunk: {
name: (entrypoint) => `runtime-${entrypoint.name}`,
},
// 通過Terser壓縮js代碼
minimizer: [
new TerserWebpackPlugin({
// 開啟快取
cache: true,
// 開啟多行程打包
parallel: true,
// 啟用sourceMap,否則會被壓縮掉,
sourceMap: true,
}),
],
},
/**
* 引數
* source-map:錯誤代碼的準確資訊和源代碼的錯誤位置 并且能夠匯出對應的源代碼
* inline-source-map:列印輸出的檔案位置 可定位到源代碼的位置
* hidden-source-map:列印輸出的是打包后的代碼 可定位到定位打包后的位置 不可以追溯到源代碼的位置
* eva-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置,
* nosource-source-map:錯誤和輸出資訊的準確位置,不可追溯到源代碼的行列位置,
* cheap-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行位置,
* cheap-module-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置 會將webpack配置等資訊添加進來
*/
devtool: "source-map", // 構建后代碼到源代碼的有一種映射技術,js輸出目錄下回多出一個xxx.js.map檔案,如果構建代碼出錯了,通過映射關系能找到源代碼的位置,非常利于除錯代碼,但是也會造成代碼被盜用的安全性問題,
};
package.json詳細配置
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/polyfill": "^7.11.5",
"@babel/preset-env": "^7.11.5",
"add-asset-html-webpack-plugin": "^3.1.3",
"babel-loader": "^8.1.0",
"core-js": "^3.6.5",
"css-loader": "^4.3.0",
"eslint": "^7.9.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.0",
"file-loader": "^6.1.0",
"html-loader": "^1.3.1",
"html-webpack-plugin": "^4.5.0",
"jquery": "^3.5.1",
"less": "^3.12.2",
"less-loader": "^7.0.1",
"mini-css-extract-plugin": "^0.11.2",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"style-loader": "^1.2.1",
"terser-webpack-plugin": "^4.2.2",
"thread-loader": "^3.0.0",
"url-loader": "^4.1.0",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"workbox-webpack-plugin": "^5.1.4"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"brower": true
}
},
"sideEffects": [
"*.css"
]
}
寄語
一篇肝了好久的webpack,篇幅很長再加上個人理解可能會有瑕疵,希望大牛別噴,給出的詳細webpack.config.js檔案我也已經測驗過了,我寫了很詳細的注釋,希望能幫到大家!但是如果轉載的話希望大家也能注明一下出處!
支持
個人開發了一個資源網址導航網站,很多資源分享,vue專案第一次進會慢一些些,但是過后就很快了,涵蓋了生活的方方面面,認真逛逛絕對會有識訓,無廣告且有軟體分享,希望大家支持一下!n.huasenjio.top,如果進不出意外的話我會把這個開源給大家!大家的訪問也許對我就是一種鼓勵了,謝謝大家!


轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/148953.html
標籤:其他
