學習 Webpack5 之路(基礎(chǔ)篇)
點擊上方 前端瓶子君,關(guān)注公眾號
回復算法,加入前端編程面試算法每日一題群
前言
對我來說,掌握一個工具最好的方式,就是在學習的過程中,總結(jié)并記錄,嘗試把自己學到的東西進行表達并分享,在分享的過程中,找到一個個同行的小伙伴,一起交流、學習,感受到學習技術(shù)的簡單和純粹。
《學習 Webpack5 之路》系列文章,標題靈感來自樸樹的《平凡之路》,一直渴望一場走到東極島的公路旅行,或許學習之路也能和平凡之路一樣,讓我獲得滿足和快樂。
《學習 Webpack5 之路》系列文章將分為以下 4 個系列,敬請期待:
基礎(chǔ)篇 實踐篇 優(yōu)化篇 原理篇
本文依賴的 webpack 版本信息如下:
webpack-cli\@4.7.2[1] webpack\@5.46.0[2]
一、Webpack 是什么
引入 webpack 官網(wǎng)[3] 介紹:
本質(zhì)上,webpack 是一個現(xiàn)代 JavaScript 應用程序的_靜態(tài)模塊打包器(module bundler)_ 。當 webpack 處理應用程序時,它會遞歸地構(gòu)建一個_依賴關(guān)系圖(dependency graph)_ ,其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle。
webpack 官網(wǎng)[4] 圖:

在圖中我們可以看到,webpack 將左側(cè)錯綜復雜的各自不同類型文件的模板依賴關(guān)系,包括 .js、.hbs、.cjs、.sass、.jpg、.png 等類型文件,打包成 .js、.css、.jpg、.png 4 種類型的靜態(tài)資源。
簡單來說,webpack 就是一個靜態(tài)資源打包工具,負責將項目中依賴的各個模塊,打包成一個或多個文件。
二、為什么選擇 Webpack
本文不進行其他打包工具和 webpack 的優(yōu)劣對比,僅介紹 webpack 能為開發(fā)者做的工作。
1. 模塊化開發(fā)
在沒有各個 webpack 搭建的腳手架(create-react-app、vue-cli 等等)之前,我們通過在 HTML5 文件里引入一個個 Javascript 文件來進行開發(fā),這就可能導致并行請求數(shù)量過多、存在重復代碼等問題。
而通過 webpack,我們可以使用 import、require 來進行模塊化開發(fā)。
在 webpack 中一切皆模塊,js、css、圖片、字體都是模塊,而且支持靜態(tài)解析、按需打包、動態(tài)加載、代碼分離等功能,幫助我們優(yōu)化代碼,提升性能。
import { Hello } from './hello.js'
import './assets/style.css'
import MyImage './assets/img.jpg'
復制代碼
2. 新語法
Javascript、CSS 的語法規(guī)范在不斷更新,但是瀏覽器的兼容性卻不能同步的更新,開發(fā)者可以通過 webpack 預處理器進行編譯,自由的使用 JS、CSS 等語言的新語法。
webpack 使用 loader[5] 對文件進行預處理。你可以構(gòu)建包括 JavaScript 在內(nèi)的任何靜態(tài)資源,如 Less、Sass、ES6、TypeScript。
通過預處理器將 TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS、ES6 編譯成 ES5 等。
開發(fā)者還可以使用 Node.js 輕松編寫自己的 loader。
常用預處理器:
`babel-loader`[6] 使用 Babel[7] 加載 ES2015+ 代碼并將其轉(zhuǎn)換為 ES5; `less-loader`[8] 加載并編譯 LESS 文件; `sass-loader`[9] 加載并編譯 SASS/SCSS 文件; `postcss-loader`[10] 使用 PostCSS[11] 加載并轉(zhuǎn)換 CSS/SSS 文件。
3. 主流框架腳手架
Vue 腳手架 vue-cli、React 腳手架 creact-react-app、Taro 腳手架 taro-cli 都是使用 webpack,開發(fā)者掌握 webpack 后,可以自由配置腳手架,根據(jù)項目需要,調(diào)整 webpack 配置,以提高項目性能。
4. 其他
webpack 除了讓開發(fā)者能夠擁有【模塊化開發(fā)+新語言+新框架】的開發(fā)體驗。
還有以下優(yōu)點:
擁有依賴管理、動態(tài)打包、代碼分離、按需加載、代碼壓縮、靜態(tài)資源壓縮、緩存等配置; webpack 擴展性強,插件機制完善,開發(fā)者可自定義插件、loader; webpack 社區(qū)龐大,更新速度快,輪子豐富;
如使用 ant-design 搭建的中后臺項目,ant-desgin 提供了 webpack 定制主題的相關(guān)文檔,較其他打包工具定制起來就簡單很多,易上手。
因為 webpack 的這些優(yōu)點,大部分的大型項目會選擇 webpack 進行項目構(gòu)建。
三、Webpack 的基本概念介紹
1. dependency graph(依賴圖)
上文有提到,當 webpack 處理應用程序時,它會遞歸地構(gòu)建一個_依賴關(guān)系圖(dependency graph)_,那么依賴關(guān)系圖是什么呢?
依賴圖指的就是文件和文件直接的依賴關(guān)系,如上文引入過的圖:

webpack 通過依賴關(guān)系圖可以獲取非代碼資源,如 images 或 web 字體等。并會把它們作為 依賴 提供給應用程序。
每個模塊都可以明確表述它自身的依賴,在打包時可根據(jù)依賴進行打包,避免打包未使用的模塊。
2. entry(入口)
入口是指依賴關(guān)系圖的開始,從入口開始尋找依賴,打包構(gòu)建。
webpack 允許一個或多個入口配置。
配置示例如下:
module.exports = {
entry: 'index.js',
};
復制代碼

3. output(輸出)
輸出則是用于配置 webpack 構(gòu)建打包的出口,如打包的位置,打包的文件名等等。
配置示例如下:
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
復制代碼

4. loader
webpack 自帶 JavaScript 和 JSON 文件的打包構(gòu)建能力,無需格外配置。
而其他類型的文件,如 CSS、TypeScript,則需要安裝 loader 來進行處理。
loader 讓 webpack 能夠去處理其他類型的文件,并將它們轉(zhuǎn)換為有效 模塊[12],以供應用程序使用,以及被添加到依賴圖中。
配置示例如下:
module.exports = {
module: {
rules: [{ test: /.txt$/, use: 'raw-loader' }],
},
};
復制代碼

5. plugin(插件)
插件則是用于擴展 webpack 的能力,常見的插件有:
ProgressBarPlugin[13]:編譯進度條; BundleAnalyzerPlugin[14]:打包體積分析; MiniCssExtractPlugin[15]:提取 CSS 到獨立 bundle 文件。
配置示例如下:
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通過 npm 安裝
module.exports = {
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
復制代碼
插件豐富,開發(fā)者社區(qū)同樣提供了大量插件,也使得 webpack 的可用功能更加多樣。
6. mode(模式)
webpack5 提供了模式選擇,包括開發(fā)模式、生產(chǎn)模式、空模式,并對不同模式做了對應的內(nèi)置優(yōu)化。可通過配置模式讓項目性能更優(yōu)。
配置示例如下:
module.exports = {
mode: 'development',
};
復制代碼
7. resolve(解析)
resolve 用于設(shè)置模塊如何解析,常用配置如下:
alias:配置別名,簡化模塊引入; extensions:在引入模塊時可不帶后綴; symlinks:用于配置 npm link 是否生效,禁用可提升編譯速度。
配置示例如下:
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.d.ts'],
alias: {
'@': paths.appSrc,
},
symlinks: false,
}
}
復制代碼
8. optimization(優(yōu)化)
optimization 用于自定義 webpack 的內(nèi)置優(yōu)化配置,一般用于生產(chǎn)模式提升性能,常用配置項如下:
minimize:是否需要壓縮 bundle; minimizer:配置壓縮工具,如 TerserPlugin、OptimizeCSSAssetsPlugin; splitChunks:拆分 bundle; runtimeChunk:是否需要將所有生成 chunk 之間共享的運行時文件拆分出來。
配置示例如下:
module.exports = {
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 語法來擴展現(xiàn)有的 minimizer(即 `terser-webpack-plugin`),將下一行取消注釋
// `...`,
new CssMinimizerPlugin(),
],
splitChunks: {
// include all types of chunks
chunks: 'all',
// 重復打包問題
cacheGroups:{
vendors:{ //node_modules里的代碼
test: /[\\/]node_modules[\\/]/,
chunks: "all",
name: 'vendors', //chunks name
priority: 10, //優(yōu)先級
enforce: true
}
}
},
},
}
復制代碼
以上對 webpack 的基本概念做了簡單的介紹,為后續(xù)實踐篇做準備。
四、總結(jié)
本文從 webpack 是什么、為什么選擇 webpack、webpack的基本概念介紹 3個角度進行講述,從 Webpack 基礎(chǔ)著手,和你一起了解 webpack。
《學習 Webpack5 之路》系列文章將分為以下 4 個系列:
基礎(chǔ)篇 實踐篇 優(yōu)化篇 原理篇
下一篇《學習 Webpack5 之路(實踐篇)》將從實踐出發(fā),一起完成一個比較完整的 webpack 配置,敬請期待。
本文源碼:webpack Demo0:https://github.com/jiaozitang/webpack-demo/tree/release_v0
希望能對你有所幫助,感謝閱讀~
別忘了點個贊鼓勵一下我哦,筆芯??
關(guān)于本文
來源:清湯餃子
https://juejin.cn/post/6991630925792542750
