webpack是優秀的前端構建工具,靜態資源打包器,可以根據模組依賴關係進行靜態資源分析,快速打包生成相對應瀏覽器可以直接識別的靜態資源!
1)node環境
2)vs code編輯器
1)入口檔案:
開始打包第一個檔案稱為入口檔案,通常經過在入口檔案中引入其他資源,形成資源關係樹狀圖。webpack根據依賴關係進行一次處理。
2)chunk程式碼塊:
管理webpack內部的打包程序,chunk可以分為「入口」和「子程式碼塊」,入口檔案就是一個chunk,預設的webpack打包設定是一個入口檔案是一個chunk,打包生成一個bundle。但是如果出現程式碼分割的情況下,有多個chunk打包生成一個bundle。
3)bundle:
通過處理入口檔案中的關係依賴,最後打包輸出成為瀏覽器可以直接識別的靜態資原始檔就是bundle。
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資料夾中,不會影響其他專案,起到獨立的作用!
入口檔案指示,設定wepack以哪個入口檔案進行打包分析等引數。
entry: "./src/main.js",
出口檔案指示,設定webpack打包後的資源bundle輸出資源的路徑及引數。
output: {
filename: "static/js/[name].js",
path: resolve(__dirname, "build"),
},
webpack本身僅能識別js、json程式碼,而Loader的作用就是將CSS、img、字型資源翻譯成為webpack可以識別的資源,可以識別後才可以進行打包處理!loader通過npm安裝依賴之後就可以設定,不用需要引入。
// 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, // 設定參、空格、縮排不規範的語法自動進行修復。
},
},
{
// 處理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,
},
},
],
},
外掛(plugins)可以讓webpack執行範圍更廣更為複雜的任務,設定打包優化等一下相關的作用功能,使用前需要單獨引入對應的外掛。
// 無template屬性時,預設在輸出目錄建立一個空的html檔案,並將打包後的資源引入其中。template指明檔案時,則複製檔案,並引入打包後的資源。
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
collapseWhitespace: true, // 清除空行縮排
removeAttributeQuotes: true, // 清除註釋
},
}),
// 處理CSS從js檔案中抽離生成獨立檔案
new MiniCssExtractPlugin({
filename: "static/css/app.css", // 檔案輸出目錄
}),
// Css壓縮外掛,需要在package.json中定義sideEffects屬性防止它壓縮去除掉一些css,less等檔案。
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"),
}),
設定webpack的工作方式,其中有開發(development)和生產(production)模式,開發環境設定簡單,能夠使程式碼能夠跑在本地即可,生產模式相關複雜,需要處理網站執行上線時的優化等操作。
// mode: "development",
mode: "production", // 設定webpack的工作環境
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"),
},
打包構架去除無用程式碼,必須是使用ES6模組化引入以及必須指定production環境,自動開啟treeshaking模式,減少程式碼體積。package.json中設定sideEffects: false所有程式碼均開啟樹搖模式,但可能會幹掉無辜的css等檔案。 若標記為sideEffects: ["*.css"]時則不會幹掉所匹配的檔案。
通過es6語法引入,延時載入,觸發一定行為才進行請求載入,不是開局就全部載入進來,那樣會增加首次載入的時間,也有著程式碼分隔的特性,會被單獨分割成一個單獨檔案。
// 動態js引入,單獨打包生成一個檔案,並給定檔名。也會有懶載入的現象。新增預載入webpackPrefetch關鍵字。
import(/*webpackChunkName: 'test',webpackPrefetch: true*/ "./test.js")
.then((res) => {
console.log("檔案載入成功", res);
})
.catch((err) => {
console.log("檔案載入失敗", err);
});
等其他瀏覽器空閒了再偷偷載入,請求到檔案資料了,觸發行為的時候再去讀取快取中的資料,懶載入的方式上新增新增預載入webpackPrefetch關鍵字。
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);
});
無網路時,重新整理仍然可以存取到已經載入的網頁,藉助了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);
});
});
}
構建後程式碼到原始碼的有一種對映技術,如果構建程式碼出錯了,通過對映關係能找到原始碼的位置,非常利於偵錯程式碼,但是也會造成程式碼被盜用的安全性問題。詳細引數移步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檔案。
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檔案,如果構建程式碼出錯了,通過對映關係能找到原始碼的位置,非常利於偵錯程式碼,但是也會造成程式碼被盜用的安全性問題。
};
{
"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,如果進不出意外的話我會把這個開源給大家!大家的存取也許對我就是一種鼓勵了,謝謝大家!