欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)邀請(qǐng)碼778899分享:webpack學(xué)習(xí)

Joom精選閣綜合2025-05-05510

柚子快報(bào)邀請(qǐng)碼778899分享:webpack學(xué)習(xí)

http://yzkb.51969.com/

webpack學(xué)習(xí)筆記

參考文檔: Webpack官網(wǎng)中文文檔學(xué)習(xí)視頻: Webpack原理與實(shí)踐

溫故webpack打包知識(shí),忘記了就回頭看看~ 根據(jù)學(xué)習(xí)視頻學(xué)習(xí)整理,不為一一對(duì)應(yīng)筆記,主要是根據(jù)對(duì)學(xué)習(xí)視頻知識(shí)的梳理~ PS:上學(xué)習(xí)視頻是基于webpack4的,我這邊運(yùn)行時(shí)基于webpack5的,不對(duì)的地方已經(jīng)按照官方文檔進(jìn)行定義配置

初始化項(xiàng)目

環(huán)境要求:node+npm+webpack

初始化 npm 項(xiàng)目

npm init -y

安裝 webpack 和 webpack-cli:

npm install --save-dev webpack webpack-cli

創(chuàng)建項(xiàng)目

建立webpack.config.js文件新建src文件夾,新建打包入口文件main.js webpack.config.js

const path = require('path');

module.exports = {

//定義入口文件

entry: './src/main.js',

// 定義輸出文件名

output:{

//定義輸出名稱

filename:'bundle.js',

//定義輸出路徑

path: path.join(__dirname, "/dist"),

}

}

main.js

alert('Hello world!')

定義打包命令package.json中script

運(yùn)行npm run build 則打包文件,默認(rèn)根據(jù)webpack.config.js配置打包

"scripts": {

"build": "webpack"

}

在根目錄建立index.html文件,通過(guò)script標(biāo)簽引入打包的文件(后面通過(guò)插件htlm-webpack-plugin自動(dòng)生成,則刪除此文件,直接自動(dòng)打包到dist文件夾中,并會(huì)自動(dòng)引入打包.js文件)

Webpack Plugin Demo

安裝server運(yùn)行靜態(tài)服務(wù)器

運(yùn)行serve則打開(kāi)當(dāng)前目錄,若有index.html默認(rèn)運(yùn)行index.html文件

npm install -g serve

運(yùn)行

當(dāng)前開(kāi)始時(shí)運(yùn)行的自定義的index.html看效果,

serve .

后續(xù)運(yùn)行dist文件夾的自動(dòng)生成的index.html看效果

serve dist

模塊化標(biāo)準(zhǔn)規(guī)范

瀏覽器:ES Module (主流的打包方案)Nodejs: Commonjs(內(nèi)置的環(huán)境系統(tǒng))

Entry(入口):

Webpack 的打包過(guò)程從入口文件開(kāi)始。入口文件可以是一個(gè)或多個(gè),指定了應(yīng)用程序的起點(diǎn)。

// webpack.config.js

module.exports = {

entry: './src/index.js'

};

Output(輸出):

配置打包后的文件輸出位置和文件名。

// webpack.config.js

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

path: __dirname + '/dist'

}

};

Loaders(加載器):

Loaders 讓 Webpack 能夠處理非 JavaScript 文件!!! 如 CSS、圖片、字體等。通過(guò)配置 loaders,Webpack 可以將這些文件轉(zhuǎn)換為可以被應(yīng)用程序使用的模塊。 具體每個(gè)loader作用以及更多l(xiāng)oader查看官網(wǎng),在這里配置最常見(jiàn)的loader

常見(jiàn)loader如下:

style-loader & css-loaderfile-loader & url-loaderhtml-loaderbabel-loader自制loader…

安裝依賴

npm i style-loader css-loader file-loader url-loader html-loader babel-loader

配置應(yīng)用

const webpack = require('webpack');

const path = require("path");

module.exports = {

mode: "none",

entry: "./src/main.js",

output: {

filename: "[name]-[chunkhash:8]-bundle.js",

path: path.join(__dirname, "/dist"),

},

module: {

rules: [

{

test: /\.m?js$/,

exclude: /(node_modules|bower_components)/,

use: {

loader: "babel-loader",

options: {

//將ES Modules轉(zhuǎn)換為CommonJS

presets: [

['@babel/preset-env', {

//默認(rèn)是auto自動(dòng),寫了commonjs是強(qiáng)制轉(zhuǎn)換為commonjs,此時(shí)usedExports無(wú)法生效,即tree shaking無(wú)法生效

modules: 'commonjs'

}]

],

}

}

},

{

test: /\.html$/,

use: 'html-loader',

},

{

test: /\.css$/,

use: [

MiniCssExtractPlugin.loader,

'css-loader']

},

{

test: /\.png$/,

use: {

loader: "url-loader",

options: {

name: '[name].[hash:8].[ext]',

outputPath: 'images/',

publicPath: 'images/',

limit: 10 * 1024,

}

}

}

]

}

}

自制loader詳解

自制markdown-loader為了解析引入.md文件

安裝markdown-it(webpack5用這個(gè)解析.md文件)

npm i markdown-it

新建markdown-loader.js

const markdownIt = require('markdown-it')();

module.exports = function markdownLoader(source) {

const html = markdownIt.render(source);

return `module.exports = ${JSON.stringify(html)}`;

};

配置使用

const webpack = require('webpack');

const path = require("path");

module.exports = {

mode: "none",

entry: "./src/main.js",

output: {

filename: "[name]-[chunkhash:8]-bundle.js",

path: path.join(__dirname, "/dist"),

},

module: {

rules: [

{

test: /\.md$/,

use: './markdown-loader'

}

]

}

}

style-loader 和 css-loader

這兩個(gè) Loaders 通常一起使用,用于處理 CSS 文件并將其引入到 JavaScript 模塊中。

css-loader:

解析 CSS 文件中的 @import 和 url() 語(yǔ)法,并將 CSS 轉(zhuǎn)換為 JavaScript 模塊。 允許你在 JavaScript 文件中通過(guò) import 或 require 引入 CSS 文件。

style-loader:

將 CSS 以

示例配置:

module.exports = {

module: {

rules: [

{

test: /\.css$/,

use: ['style-loader', 'css-loader']

}

]

}

};

file-loader 和 url-loader

這兩個(gè) Loaders 用于處理文件資源,如圖片、字體等。

file-loader:

將文件解析為 import 或 require 語(yǔ)句,并返回一個(gè)相應(yīng)的 URL。 將文件復(fù)制到輸出目錄,并根據(jù)配置返回相對(duì) URL 或絕對(duì) URL。

url-loader:

功能類似于 file-loader,但如果文件小于設(shè)定的閾值(以字節(jié)為單位),它會(huì)將文件內(nèi)容轉(zhuǎn)換為 Base64 編碼的 Data URL,嵌入到生成的 JavaScript 文件中。 超過(guò)閾值的文件仍然會(huì)使用 file-loader 處理

示例配置:

module.exports = {

module: {

rules: [

{

test: /\.(png|jpg|gif)$/,

use: [

{

loader: 'url-loader',

options: {

limit: 8192, // 8KB 以下的文件會(huì)被轉(zhuǎn)為 Base64

name: '[name].[hash:8].[ext]'

}

}

]

}

]

}

};

html-loader

html-loader:

解析 HTML 文件中的 標(biāo)簽、 標(biāo)簽和其他資源引用,將它們轉(zhuǎn)換為 import 或 require 語(yǔ)句,從而使得這些資源能夠被 Webpack 打包。 處理 HTML 文件中的資源依賴,生成正確的資源路徑。 示例配置

module.exports = {

module: {

rules: [

{

test: /\.html$/,

use: 'html-loader'

}

]

}

};

babel-loader

babel-loader: 使用 Babel 將 ES6/ES7/ES8 等現(xiàn)代 JavaScript 語(yǔ)法轉(zhuǎn)換為 ES5,從而兼容更多的瀏覽器環(huán)境。 支持 Babel 插件和預(yù)設(shè)(presets),如 @babel/preset-env,以便使用最新的 JavaScript 特性和語(yǔ)法。

示例配置:

module.exports = {

module: {

rules: [

{

test: /\.js$/,

exclude: /node_modules/,

use: {

loader: 'babel-loader',

options: {

presets: ['@babel/preset-env']

}

}

}

]

}

};

總結(jié)

style-loader & css-loader:處理 CSS 文件,解析并注入到 HTML 中。file-loader & url-loader:處理文件資源(如圖片、字體),將文件復(fù)制到輸出目錄并生成相應(yīng)的 URL,url-loader 可以將小文件內(nèi)聯(lián)到 JavaScript 中。html-loader:解析 HTML 文件中的資源引用,生成正確的資源路徑。babel-loader:使用 Babel 將現(xiàn)代 JavaScript 語(yǔ)法轉(zhuǎn)換為 ES5,以兼容更多瀏覽器環(huán)境。 通過(guò)使用這些 Loaders,Webpack 可以處理多種類型的文件資源,并將它們整合到打包輸出中,提高開(kāi)發(fā)效率和代碼兼容性。

Plugins(插件):

插件用于執(zhí)行更廣泛的任務(wù),如優(yōu)化打包結(jié)果、資源管理和環(huán)境變量注入。插件比 loaders 更強(qiáng)大,提供了更多功能。 具體每個(gè)plugins作用以及更多plugins查看官網(wǎng),在這里配置最常見(jiàn)的plugins

常見(jiàn)plugins如下:

clean-webpack-pluginhtml-webpack-plugincopy-webpack-pluginmini-css-extract-plugincss-minimizer-webpack-pluginterser-webpack-plugin自制plugins…更多plugins詳見(jiàn)官網(wǎng)

安裝依賴

npm i --save-dev clean-webpack-plugin html-webpack-plugin copy-webpack-plugin mini-css-extract-plugin css-minimizer-webpack-plugin terser-webpack-plugin

配置應(yīng)用

// clean-webpack-plugin 清除上次生成的dist目錄 避免遺留文件

const {CleanWebpackPlugin} = require("clean-webpack-plugin");

// html-webpack-plugin 通過(guò)webpack輸出html文件 index.html中的script路徑引用 是否正常

const HTMLWebpackPlugin = require("html-webpack-plugin");

// copy-webpack-plugin 拷貝不需要打包的目錄

const CopyWebpackPlugin = require("copy-webpack-plugin");

//提取css文件

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

// 壓縮css

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

//js壓縮插件

const TerserPlugin = require('terser-webpack-plugin');

const webpack = require('webpack');

const path = require("path");

module.exports = {

mode: "none",

entry: "./src/main.js",

output: {

filename: "[name]-[chunkhash:8]-bundle.js",

path: path.join(__dirname, "/dist"),

},

//相當(dāng)于tree shaking:集中配置webpack當(dāng)中優(yōu)化功能

optimization: {

// 壓縮代碼 負(fù)責(zé)【搖掉】他們 開(kāi)發(fā)環(huán)境一般不壓縮

minimize: false,

//minimizer默認(rèn)壓縮,配置為數(shù)組方式則為自定義配置打包壓縮,CssMinimizerPlugin壓縮css,TerserPlugin壓縮js

minimizer: [

new CssMinimizerPlugin(),

new TerserPlugin()

]

},

plugins: [

new CleanWebpackPlugin(),

// 用于生成index.html

new HTMLWebpackPlugin({

title: "Webpack Plugin Demo",

meta: {

viewport: "width=device-width, initial-scale=1"

},

// 按照模版輸出

// template: "./src/index.html",

}),

//用于熱更新

new webpack.HotModuleReplacementPlugin(),

//按需加載css文件

new MiniCssExtractPlugin({

// :8指定長(zhǎng)度 推薦使用chunkhash

// * hash:項(xiàng)目中任何一個(gè)地方改動(dòng),打包都會(huì)造成全部文件變化

// * chunkhash推薦: 根據(jù)修改代碼處,打包只變化修改的代碼處文件名

// * contenthash:根據(jù)代碼修改代碼處,修改只變化內(nèi)容的文件名

// filename:'[name]-[hash:8].bundle.css',

filename: '[name]-[chunkhash:8].bundle.css',

// filename:'[name]-[contenthash].bundle.css',

}),

// 壓縮css

new CssMinimizerPlugin()

]

}

自制plugins詳解

自制my-plugins插件,用于清除js文件中的注釋!

通在webpack生命周期的鉤子中掛載函數(shù)實(shí)現(xiàn)擴(kuò)展 !?。?類似事件 webpack給每個(gè)環(huán)節(jié)埋下鉤子 掛載不同任務(wù) 就可擴(kuò)展webpack能力。webpack要求我們鉤子必須是一個(gè)函數(shù)或者是一個(gè)包含apply方法的對(duì)象

配置如下:

const path = require("path");

// 自制插件 plugin 通在webpack生命周期的鉤子中掛載函數(shù)實(shí)現(xiàn)擴(kuò)展 !??! 類似事件 webpack給每個(gè)環(huán)節(jié)埋下鉤子 掛載不同任務(wù) 就可擴(kuò)展webpack能力

//webpack要求我們鉤子必須是一個(gè)函數(shù)或者是一個(gè)包含apply方法的對(duì)象

//編寫一個(gè)插件 去除js文件中的注釋

class MyPlugin {

apply(compiler) {

compiler.hooks.emit.tap('MyPlugin', compilation => {

//compilation 理解為此次打包的上下文

for (const name in compilation.assets) {

console.log(`Processing asset: ${name}`);

if (name.endsWith(".js")) {

const content = compilation.assets[name].source();

console.log(`Original content: \n${content}`);

const withoutComments = content.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '');

console.log(`Content without comments: \n${withoutComments}`);

compilation.assets[name] = {

source: () => withoutComments,

//必須的方法

size: () => withoutComments.length,

};

}

}

});

}

}

module.exports = {

mode: "none",

entry: "./src/main.js",

output: {

filename: "[name]-[chunkhash:8]-bundle.js",

path: path.join(__dirname, "/dist"),

},

plugins: [

// 自制插件 用于清除js文件中的注釋

new MyPlugin(),

]

}

配置使用

const webpack = require('webpack');

const path = require("path");

module.exports = {

mode: "none",

entry: "./src/main.js",

output: {

filename: "[name]-[chunkhash:8]-bundle.js",

path: path.join(__dirname, "/dist"),

},

module: {

rules: [

{

test: /\.md$/,

use: './markdown-loader'

}

]

}

}

clean-webpack-plugin

作用:在每次構(gòu)建之前清理 /dist 文件夾,確保輸出目錄中只有構(gòu)建過(guò)程中生成的文件。主要功能:

刪除舊的文件,防止冗余文件堆積,保持輸出目錄整潔。 安裝依賴

npm i --save-dev clean-webpack-plugin

配置

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {

plugins: [

new CleanWebpackPlugin()

]

};

html-webpack-plugin

作用:生成 HTML 文件,并自動(dòng)注入打包生成的 JavaScript 和 CSS 文件。 主要功能:

根據(jù)模板或默認(rèn)生成 HTML 文件。自動(dòng)注入所有打包生成的資源(例如 JS、CSS 文件)。支持設(shè)置模板、文件名、標(biāo)題等選項(xiàng)。 安裝依賴

npm i --save-dev html-webpack-plugin

配置

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

plugins: [

new HtmlWebpackPlugin({

template: './src/index.html',

filename: 'index.html',

title: 'My App'

})

]

};

copy-webpack-plugin

作用:將文件或文件夾從一個(gè)位置復(fù)制到另一個(gè)位置(通常是復(fù)制靜態(tài)資源到輸出目錄)。 主要功能:

復(fù)制不需要進(jìn)行編譯處理的文件,如圖片、字體、靜態(tài) HTML 等。 安裝依賴

npm i --save-dev copy-webpack-plugin

配置

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {

plugins: [

new CopyWebpackPlugin({

patterns: [

{ from: 'public', to: 'dist' }

]

})

]

};

mini-css-extract-plugin

通過(guò)MiniCssExtractPlugin插件實(shí)現(xiàn)css文件的按需加載。建議css文件超過(guò)150kb才考慮是否提取到文件當(dāng)中,會(huì)單獨(dú)生成一個(gè)文件。

作用:將 CSS 提取到單獨(dú)的文件,而不是嵌入到 JavaScript 中。 主要功能:

提高 CSS 加載速度,減少 JavaScript 文件的體積。支持按需加載 CSS。 安裝依賴

npm i --save-dev mini-css-extract-plugin

配置

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {

module: {

rules: [

{

test: /\.css$/,

use: [MiniCssExtractPlugin.loader, 'css-loader']

}

]

},

plugins: [

new MiniCssExtractPlugin({

filename: '[name].[contenthash].css'

})

]

};

css-minimizer-webpack-plugin

optimize-css-assets-webpack-plugincss-minimizer-webpack-plugin

PS:由于 optimize-css-assets-webpack-plugin 版本與 webpack 版本之間的兼容性問(wèn)題。 具體來(lái)說(shuō),optimize-css-assets-webpack-plugin@6.0.1 需要 webpack@^4.0.0,而我當(dāng)前的項(xiàng)目中使用的是 webpack@5.91.0。 則不適用安裝此,我將安裝css-minimizer-webpack-plugin代替。 當(dāng)然,你也可以使用 --legacy-peer-deps 參數(shù)來(lái)忽略兼容性檢查,但這可能會(huì)導(dǎo)致其他問(wèn)題。

作用:壓縮和優(yōu)化 CSS 文件,減少文件體積,提高加載速度。主要功能:

使用 cssnano 庫(kù)進(jìn)行 CSS 的壓縮優(yōu)化。通常與 mini-css-extract-plugin 配合使用。通常與 terser-webpack-plugin配合使用,壓縮js文件。

安裝依賴

壓縮css

npm i --save-dev css-minimizer-webpack-plugin

壓縮js

為了區(qū)分環(huán)境,使用optimization中minimizer進(jìn)行,一般默認(rèn)壓縮,配置為數(shù)組方式則為自定義配置打包壓縮,CssMinimizerPlugin壓縮css,則需要安裝TerserPlugin壓縮js)

npm install --save-dev terser-webpack-plugin

引入并使用

// 引入依賴壓縮css

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

//js壓縮插件

const TerserPlugin = require('terser-webpack-plugin');

module.exports={

// 壓縮建議在生產(chǎn)環(huán)境才輸出,建議放在optimization中minimize統(tǒng)一配置

optimization:{

//可以由這里控制是否壓縮,開(kāi)發(fā)環(huán)境設(shè)置為false則不壓縮,生產(chǎn)環(huán)境設(shè)置為true開(kāi)啟壓縮

minimize:true,

//minimizer默認(rèn)壓縮,配置為數(shù)組方式則為自定義配置打包壓縮,CssMinimizerPlugin壓縮css,TerserPlugin壓縮js

minimizer: [

new CssMinimizerPlugin(),

new TerserPlugin()

]

},

//這里配置直接壓縮不區(qū)分環(huán)境

// plugins:[

// // 壓縮css

// new CssMinimizerPlugin()

// ]

}

terser-webpack-plugin

作用:壓縮和優(yōu)化 JavaScript 文件,減少文件體積,提高加載速度。主要功能:

使用 Terser 庫(kù)進(jìn)行 JavaScript 的壓縮優(yōu)化。替代 Webpack 4 之前的 UglifyJS 插件。

安裝依賴

npm i --save-dev terser-webpack-plugin

配置

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {

optimization: {

minimize: true,

minimizer: [new TerserPlugin()]

}

};

總結(jié)

clean-webpack-plugin:在每次構(gòu)建之前清理輸出目錄,保持目錄整潔。html-webpack-plugin:生成 HTML 文件并自動(dòng)注入打包生成的資源。copy-webpack-plugin:復(fù)制文件或文件夾到輸出目錄。mini-css-extract-plugin:將 CSS 提取到單獨(dú)的文件,提高加載速度。css-minimizer-webpack-plugin:壓縮和優(yōu)化 CSS 文件,減少文件體積。terser-webpack-plugin:壓縮和優(yōu)化 JavaScript 文件,減少文件體積。 通過(guò)使用這些插件,Webpack 可以更高效地處理和優(yōu)化各種資源,提高構(gòu)建和加載性能。

webpack-dev-server

自動(dòng)刷新功能:將打包結(jié)果暫時(shí)存放在內(nèi)存當(dāng)中,沒(méi)有進(jìn)入磁盤讀寫,webpack-dev-server從內(nèi)存當(dāng)中將變化讀取出來(lái),發(fā)送到瀏覽器,添加–open默認(rèn)自動(dòng)打開(kāi)我們的瀏覽器,這里添加到script命令里,我配置到dev,運(yùn)行一次就可以看到一邊編碼一邊預(yù)覽的環(huán)境

安裝依賴

npm install --save-dev webpack-dev-server

配置運(yùn)行命令在package.json中

"scripts": {

"dev": "webpack-dev-server --open"

}

運(yùn)行

npm run dev

運(yùn)行之后,在文件中修改瀏覽器內(nèi)容在保存后便會(huì)直接變化,無(wú)需刷新方可更新

devtools(source-map)

設(shè)置屬性 devtool: ‘source-map’ 一般效果最好的生成的最慢,約為12種,每種方式效率和效果不同

開(kāi)發(fā)環(huán)境偏向選擇cheap-module-source-map 轉(zhuǎn)換過(guò)后差異過(guò)大 首次打包慢無(wú)所謂 重寫打包就快了生產(chǎn)環(huán)境 選擇none 為了不暴露源代碼 隱患 調(diào)試是開(kāi)發(fā)階段的事情 或者nosources-source-map

module.exports={

devtool: 'cheap-module-source-map'

}

點(diǎn)擊查看更多source-map

HMR熱更新

Hot Module Replacement 模塊熱替換或者叫模塊熱更新。 Webpack 的熱更新(Hot Module Replacement, HMR)是一種允許在運(yùn)行時(shí)替換、添加或刪除模塊,而無(wú)需重新加載整個(gè)頁(yè)面的技術(shù)。HMR 的核心原理包括模塊熱替換、依賴管理以及狀態(tài)保持。以下是 Webpack 熱更新的詳細(xì)實(shí)現(xiàn)原理

Webpack 熱更新的工作流程:

檢測(cè)變更:

Webpack 使用文件系統(tǒng)監(jiān)視工具(如 chokidar)監(jiān)視源代碼文件的變更。當(dāng)開(kāi)發(fā)者修改文件并保存時(shí),Webpack 偵測(cè)到這些變化。

編譯模塊:

一旦檢測(cè)到變更,Webpack 重新編譯受影響的模塊(模塊包括 JavaScript、CSS、模板文件等)。這一步只重新編譯變更的部分,而不是整個(gè)應(yīng)用。

生成補(bǔ)?。?/p>

編譯完成后,Webpack 生成更新的模塊,并將這些模塊打包成補(bǔ)丁(Hot Update Chunk),包含變更的模塊和相應(yīng)的依賴關(guān)系。

通知客戶端: Webpack 開(kāi)發(fā)服務(wù)器(Webpack Dev Server)通過(guò) WebSocket 向客戶端(瀏覽器)發(fā)送更新通知。通知內(nèi)容包括更新的模塊 ID 和哈希值等信息。應(yīng)用更新:

客戶端收到更新通知后,通過(guò) WebSocket 從開(kāi)發(fā)服務(wù)器請(qǐng)求補(bǔ)丁數(shù)據(jù)。客戶端運(yùn)行 HMR 運(yùn)行時(shí)邏輯,動(dòng)態(tài)地將新的模塊替換進(jìn)運(yùn)行中的應(yīng)用。

Webpack HMR 關(guān)鍵組件

Webpack Dev Server Webpack Dev Server 是一個(gè)開(kāi)發(fā)服務(wù)器,提供靜態(tài)文件服務(wù)、實(shí)時(shí)重載以及 HMR 支持。它在內(nèi)存中保存最新的編譯結(jié)果,減少文件系統(tǒng) I/O 操作,提高性能。 HMR Runtime HMR 運(yùn)行時(shí)是注入到打包輸出中的一段 JavaScript 代碼,負(fù)責(zé)處理模塊更新。它通過(guò) WebSocket 與 Webpack Dev Server 通信,接收更新通知并應(yīng)用補(bǔ)丁。

熱更新的應(yīng)用過(guò)程:

更新檢查:

HMR Runtime 通過(guò) WebSocket 接收來(lái)自 Webpack Dev Server 的更新通知。

請(qǐng)求更新模塊:

HMR Runtime 發(fā)送請(qǐng)求獲取更新模塊的補(bǔ)丁數(shù)據(jù)(包含新的模塊代碼和更新的哈希值)。

模塊熱替換:

HMR Runtime 加載新的模塊代碼,調(diào)用模塊的 accept 或 dispose 鉤子函數(shù),執(zhí)行模塊熱替換邏輯。 accept 鉤子函數(shù)允許模塊在更新時(shí)執(zhí)行自定義邏輯,例如重新渲染組件。 dispose 鉤子函數(shù)允許模塊在被替換前執(zhí)行清理工作,例如移除事件監(jiān)聽(tīng)器或保存狀態(tài)。

例子:當(dāng)然也可在本main.js中體會(huì)

if (module.hot) {

module.hot.accept('./moduleA.js', function() {

console.log('moduleA updated');

// 處理更新后的邏輯

render();

});

module.hot.dispose(function() {

console.log('Cleaning up before module is replaced');

// 清理邏輯,例如移除事件監(jiān)聽(tīng)器

});

}

function render() {

const content = require('./moduleA.js');

document.getElementById('app').innerHTML = content;

}

render();

在這個(gè)示例中,當(dāng) moduleA.js 被更新時(shí),HMR Runtime 會(huì)調(diào)用 accept 鉤子函數(shù)重新渲染內(nèi)容,并在模塊被替換前調(diào)用 dispose 鉤子函數(shù)進(jìn)行清理工作。

總結(jié)

Webpack 的熱更新機(jī)制通過(guò)監(jiān)聽(tīng)文件變化、重新編譯受影響模塊、生成并應(yīng)用補(bǔ)丁來(lái)實(shí)現(xiàn)模塊的熱替換。 關(guān)鍵組件包括 Webpack Dev Server 和 HMR Runtime,它們共同配合,使得開(kāi)發(fā)者可以在不刷新整個(gè)頁(yè)面的情況下高效地進(jìn)行模塊更新。 通過(guò)使用 HMR,開(kāi)發(fā)者可以顯著提升開(kāi)發(fā)體驗(yàn)和效率。

開(kāi)啟熱更新,配置package.json文件 配置–hot

"scripts": {

"dev": "webpack-dev-server --open --hot"

}

不同環(huán)境中的配置

通過(guò)運(yùn)行命令env區(qū)別: 打包命令 配置在script上

webpack --env production

實(shí)際操作 webpack.common.js 根據(jù)env判斷環(huán)境做相應(yīng)處理

const config = {

}

//生產(chǎn)環(huán)境下的配置

if(env==='production'){

config.mode = 'prodution'

config.devtool = false

config.plugin =[

...config.plugins,

new CleanWebpackPlugin(),

new CopyWebpackPlugin(['public'])

]

}

}

大型項(xiàng)目建議

不同環(huán)境對(duì)應(yīng)不同配置文件

webpack.common.js 通用配置webpack.dev.js 開(kāi)發(fā)環(huán)境配置webpack.prod.js 生產(chǎn)環(huán)境配置

webpack-merge合并邏輯

安裝依賴

npm i --save-dev webpack-merge

配置使用,比如在生產(chǎn)環(huán)境配置 webpack.prod.js中:

//通用配置

const common = require('./webpack.common');

//合并配置

const merge = require('webpack-merge');

const {CleanWebpackPlugin} = require('clean-webpack-plugin');

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = merge(common,{

mode:'production',

plugins: [

new CleanWebpackPlugin(),

new CopyWebpackPlugin(['public'])

]

})

打包命令構(gòu)建,配置在package.json中的script命令

webpack --config webpack.prod.js

definePlugin注入變量

通常用于不同環(huán)境的區(qū)別

在webpack.prod.js定義

const webpack = require('webpack');

module.exports={

mode:'none',

entry: "./src/main.js",

output:{

filename: 'bundle.js',

},

plugins:[

new webpack.DefinePlugin({

API_BASE_URL:`"https:''api/example.com"`

})

]

}

在main.js測(cè)試

//可以看到結(jié)果https:''api/example.com

console.log(API_BASE_URL);

驗(yàn)證:執(zhí)行打包npm run build:prod可以看到bundle.js有https://api.example.com

Tree Shaking 搖樹

tree shaking:將枯樹葉搖落:即意思為自動(dòng)檢測(cè)出代碼中未引用的代碼,移除未用的多余代碼。 生產(chǎn)環(huán)境默認(rèn)開(kāi)啟!生產(chǎn)模式默認(rèn)開(kāi)啟tree shaking功能! 運(yùn)用

自動(dòng)開(kāi)啟

這里我在editor.js定義了一個(gè)未被引用的console.log

開(kāi)發(fā)環(huán)境:運(yùn)行npm run build:dev打包就打印出來(lái)了,未開(kāi)啟tree shaking功能生產(chǎn)環(huán)境:運(yùn)行npm run build:prod打包就沒(méi)有打印出來(lái),生產(chǎn)模式默認(rèn)開(kāi)啟tree shaking功能

1-指定生產(chǎn)環(huán)境

或打包時(shí)候指定為生產(chǎn)環(huán)境:

package.json script配置命令

webpack --mode prodution

或者配置中指定mode

module.exports = {

mode:'prodution'

}

運(yùn)行命令

npm run build:prod

2-手動(dòng)開(kāi)啟tree shaking

主要通過(guò)配置 optimization 比如在開(kāi)發(fā)環(huán)境下配置

// 開(kāi)發(fā)環(huán)境打包配置

const common = require('./webpack.common');

// v5之前

// const merge = require('webpack-merge');

//v5版本之后 webpack-merge v5 之后的導(dǎo)入方式有所不同,你需要從 webpack-merge 包中導(dǎo)入 merge 函數(shù)。

const {merge} = require('webpack-merge');

module.exports = merge(common, {

mode: 'development',

devtool: 'cheap-module-source-map',

//相當(dāng)于tree shaking:集中配置webpack當(dāng)中優(yōu)化功能,下面二者缺一不可

optimization: {

//只導(dǎo)出使用的模塊 負(fù)責(zé)標(biāo)記【枯樹葉】

usedExports: true,

//壓縮代碼 負(fù)責(zé)【搖掉】他們

minimize: true,

}

})

運(yùn)行命令

npm run build:dev

合并模塊ConcatenateModules

主要通過(guò)在optimization配置concatenateModules:true,同時(shí)為了更好地看到效果,關(guān)閉掉minimizee:true 作用:盡可能將所有模塊合并輸出到一個(gè)函數(shù)中,就不是一個(gè)模塊對(duì)應(yīng)一個(gè)函數(shù)了。又名 Scope Hoisting 作用域提升

// 開(kāi)發(fā)環(huán)境打包配置

const common = require('./webpack.common');

// v5之前

// const merge = require('webpack-merge');

//v5版本之后 webpack-merge v5 之后的導(dǎo)入方式有所不同,你需要從 webpack-merge 包中導(dǎo)入 merge 函數(shù)。

const {merge} = require('webpack-merge');

module.exports = merge(common, {

mode: 'development',

devtool: 'cheap-module-source-map',

//相當(dāng)于tree shaking:集中配置webpack當(dāng)中優(yōu)化功能

optimization: {

//只導(dǎo)出使用的模塊 負(fù)責(zé)標(biāo)記【枯樹葉】

usedExports: true,

//壓縮代碼 負(fù)責(zé)【搖掉】他們

// minimize: true,

//這里:合并模塊!!

concatenateModules: true,

}

})

運(yùn)行查看

npm run buil

Tree Shaking & Babel

webpack發(fā)展非???,有人提出使用了babel-loader,tree shaking就會(huì)失效。 原因是 tree shaking使用的前提是ES Modules.交給Webpack打包的代碼必須使用ES Modules.而babel-loader是將ES Modules轉(zhuǎn)換成CommonJS。

情況一:babel-loader 會(huì)判斷是否usedExport,如果有,就禁用ES Module的轉(zhuǎn)換。tree shaking生效情況二:babel-loader在presets里面配置了modules為commonjs則為強(qiáng)制轉(zhuǎn)換,tree shaking不生效 具體如下代碼:

const webpack = require('webpack');

const path = require("path");

module.exports = {

mode: "none",

entry: "./src/main.js",

output: {

filename: "bundle.js",

path: path.join(__dirname, "/dist"),

},

//生產(chǎn)環(huán)境 選擇none 為了不暴露源代碼 隱患 調(diào)試是開(kāi)發(fā)階段的事情 或者nosources-source-map

devtool: 'cheap-module-source-map',

optimization: {

//?。?!只導(dǎo)出使用的模塊 負(fù)責(zé)標(biāo)記【枯樹葉】 但是使用了babel-loader就看具體情況,強(qiáng)制轉(zhuǎn)換commonjs這次就失效

usedExports: true,

//壓縮代碼 負(fù)責(zé)【搖掉】他們

minimize: true,

//這里:合并模塊!!

concatenateModules: true,

},

module: {

rules: [

{

test: /\.m?js$/,

exclude: /(node_modules|bower_components)/,

use: {

loader: "babel-loader",

options: {

//將ES Modules轉(zhuǎn)換為CommonJS

presets: [

['@babel/preset-env', {

//默認(rèn)是auto自動(dòng),寫了commonjs是強(qiáng)制轉(zhuǎn)換為commonjs,此時(shí)usedExports無(wú)法生效,即tree shaking無(wú)法生效

modules: 'commonjs'

}]

],

}

}

}

]

}

}

SideEffects副作用特性

適用前提:確保你的代碼沒(méi)有副作用!! sideEffects一般用于NPM包標(biāo)記是否有副作用,生產(chǎn)環(huán)境下默認(rèn)開(kāi)啟,開(kāi)啟了之后沒(méi)有用到的模塊就不再會(huì)打包。 在optimization中配置

標(biāo)識(shí)是否有副作用

在 Webpack 中,“副作用”(side effects)這個(gè)術(shù)語(yǔ)也有特定的意義,通常用于描述模塊是否對(duì)導(dǎo)入它的代碼產(chǎn)生額外影響。具體來(lái)說(shuō),Webpack 會(huì)使用 sideEffects 字段來(lái)標(biāo)記一個(gè)模塊或包是否包含副作用,以便進(jìn)行更好的優(yōu)化,例如 Tree Shaking(移除未使用的代碼)。

package.json中

{

"name": "my-library",

"version": "1.0.0",

"sideEffects": false

}

在這個(gè)例子中,設(shè)置 “sideEffects”: false 表示模塊沒(méi)有副作用,Webpack 可以安全地移除未使用的代碼部分。如果某些文件確實(shí)有副作用,可以指定它們:

{

"name": "my-library",

"version": "1.0.0",

"sideEffects": ["*.css", "*.scss"]

}

這告訴 Webpack 除了 .css 和 .scss 文件外,其他文件都沒(méi)有副作用。

開(kāi)啟副作用功能

在編程中,“副作用”(side effect)指的是函數(shù)或表達(dá)式在計(jì)算結(jié)果之外,還會(huì)對(duì)程序的其他部分產(chǎn)生影響的情況。通俗一點(diǎn)說(shuō),副作用是指除了返回一個(gè)值以外,函數(shù)或表達(dá)式還做了其他事情,這些事情會(huì)影響到外部的狀態(tài)或環(huán)境。比如說(shuō)有個(gè)方法Number.propotype.pad = function(){}通過(guò)原型改變Number方法這也是副作用,開(kāi)啟了副作用將不再打包這段函數(shù)

webpack.dev.js:

optimization:{

//開(kāi)啟副作用,生產(chǎn)環(huán)境默認(rèn)開(kāi)啟,沒(méi)用到的模塊不再打包

sideEffects: true

}

多入門打包

entry定義為一個(gè)對(duì)象,一個(gè)屬性就是打包的一個(gè)路徑,多個(gè)入口打包出多個(gè)結(jié)果,filename不直接定義為一個(gè)固定名稱。 但是若是希望打包出來(lái)也為多個(gè)index.html就需要獨(dú)立配置,都則將會(huì)打包到一個(gè)index.html中引入。則需在HtmlWebpackPlugin中定義chunks:[‘index’] 實(shí)現(xiàn)步驟

定義entry多個(gè)入口 對(duì)象方式修改輸出多個(gè)文件名稱區(qū)分定義輸出多個(gè)不用名稱index.html,多個(gè)引入代替一個(gè)index.html引入多個(gè)

// 開(kāi)發(fā)環(huán)境打包配置

const common = require('./webpack.common');

const HTMLWebpackPlugin = require('html-webpack-plugin');

// v5之前

// const merge = require('webpack-merge');

//v5版本之后 webpack-merge v5 之后的導(dǎo)入方式有所不同,你需要從 webpack-merge 包中導(dǎo)入 merge 函數(shù)。

const {merge} = require('webpack-merge');

const path = require("node:path");

module.exports = merge(common, {

// 1-定義多個(gè)入口

entry:{

main: './src/main.js',

hello:'./src/hello.js'

},

//2-修改輸出名稱

output: {

filename: '[name].bundle.js',

path: path.join(__dirname, "/dist"),

},

//3-定義輸出多個(gè)不同名稱index.html

plugins: [

new HTMLWebpackPlugin({

title: 'webpack main',

filename: 'main.html',

//定義chunks連接

chunks:['main']

}),

new HTMLWebpackPlugin({

title: 'webpack hello',

filename: 'hello.html',

//定義chunks連接

chunks:['hello']

})

],

mode: 'development',

devtool: 'cheap-module-source-map',

//相當(dāng)于tree shaking:集中配置webpack當(dāng)中優(yōu)化功能

optimization: {

//只導(dǎo)出使用的模塊 負(fù)責(zé)標(biāo)記【枯樹葉】

usedExports: true,

//壓縮代碼 負(fù)責(zé)【搖掉】他們 僅僅對(duì)于js文件生效 css不生效

minimize: true,

//這里:合并模塊!!

concatenateModules: true,

//副作用,開(kāi)啟了之后沒(méi)有用到的模塊就不再會(huì)打包。

sideEffects: true,

}

})

不同打包之提取公共模塊

代碼中會(huì)有相同的共用部分造成代碼復(fù)用率低。 利用optimization中配置splitChunks代碼分割為chunks:'all’開(kāi)啟提取打包公用模塊

//相當(dāng)于tree shaking:集中配置webpack當(dāng)中優(yōu)化功能

optimization: {

//提取公共部分

splitChunks:{

chunks: 'all'

}

}

打包查看

npm run build:dev

可看到dist文件中生成了多余的js文件名為二者合一公用模塊

動(dòng)態(tài)導(dǎo)入

動(dòng)態(tài)導(dǎo)入按需加載極大節(jié)省我們的帶寬以及流量,提高響應(yīng)速度。 事例情況:就是比如點(diǎn)擊菜單A顯示A內(nèi)容,菜單B顯示B內(nèi)容。而不是一開(kāi)始就加載全部AB內(nèi)容,而是做到按需加載。 具體原理:按照監(jiān)聽(tīng)菜單瞄點(diǎn),是什么瞄點(diǎn)加載什么內(nèi)容

具體原理實(shí)現(xiàn)代碼:

const render = ()=>{

const hash = window.location.hash || "#posts";

const mainElements = document.querySelector('.main');

mainElements.innerHTML = '';

if(hash==='#posts'){

import('./posts/post').then(({default:posts})=>{

mainElements.appendChild(posts());

})

}else if(hash==='#album'){

import('./posts/album').then(({default:album})=>{

mainElements.appendChild(album());

})

}

}

render();

//監(jiān)聽(tīng)改變

window.addEventListener('hashchange', render);

魔法注釋

通過(guò)分包時(shí)候添加注釋,相同的chunks name就會(huì)打包到一起

實(shí)現(xiàn)如下:

const render = () => {

const hash = window.location.hash || "#posts";

const mainElements = document.querySelector('.main');

mainElements.innerHTML = '';

if (hash === '#posts') {

//魔法注釋

import(/* webpackChunkname:'posts' */ './posts/post').then(({default: posts}) => {

mainElements.appendChild(posts());

})

} else if (hash === '#album') {

//魔法注釋

import(/* webpackChunkname:'album' */ './posts/album').then(({default: album}) => {

mainElements.appendChild(album());

})

}

}

render();

//監(jiān)聽(tīng)改變

window.addEventListener('hashchange', render);

輸出文件名 Hash

啟用靜態(tài)資源,用戶則不需要重復(fù)請(qǐng)求加載得到這些資源,整體響應(yīng)速度就會(huì)有一個(gè)大幅度提升。 為了解決:

緩存失效時(shí)間設(shè)置的過(guò)短,效果則不明顯緩存失效時(shí)間設(shè)置的過(guò)長(zhǎng),沒(méi)辦法及時(shí)更新到客戶端

生產(chǎn)模式下,文件名使用Hash哈希值,一旦資源文件發(fā)生改變,則會(huì)一起改變。 對(duì)于客戶端而言,全新的文件名就是全新的請(qǐng)求,則沒(méi)有緩存的問(wèn)題。那緩存時(shí)間設(shè)置的非常長(zhǎng),也不擔(dān)心更新問(wèn)題。

hash模式

為了減少靜態(tài)資源請(qǐng)求,設(shè)置緩存,則減少服務(wù)器的請(qǐng)求。

緩存時(shí)間設(shè)置的短,請(qǐng)求頻繁。緩存時(shí)間設(shè)置的長(zhǎng),用戶不能及時(shí)更新

解決方式:設(shè)置hash哈希值

hash:項(xiàng)目中任何一個(gè)地方改動(dòng),打包都會(huì)造成全部文件變化chunkhash推薦: 根據(jù)修改代碼處,打包只變化修改的代碼處文件名(推薦使用)contenthash:根據(jù)代碼修改代碼處,修改只變化內(nèi)容的文件名

通過(guò):length指定哈希長(zhǎng)度,默認(rèn)是20位

//提取css文件

const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports={

output:{

filename:'[name]-[chunkhash:8].bundle.js',

path: path.join(__dirname, "/dist"),

},

plugins:[

new MiniCssExtractPlugin({

filename:'[name]-[chunkhash:8].bundle.css'

})

]

}

柚子快報(bào)邀請(qǐng)碼778899分享:webpack學(xué)習(xí)

http://yzkb.51969.com/

參考閱讀

評(píng)論可見(jiàn),查看隱藏內(nèi)容
大家都在看:

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19303313.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄