?一、常見需求
1、簡單配置入口和出口,實(shí)現(xiàn)build打包功能。
入口配置(建議在配置入口文件時(shí)使用絕對(duì)路徑)
出口配置(在配置出口時(shí)只能使用絕對(duì)路徑)
[chunkhash] 生成hash字符串的方式:每次打包,webpack根據(jù)當(dāng)前chunk進(jìn)行計(jì)算,如果發(fā)現(xiàn)有代碼變化,就生成新的hash名;如果當(dāng)前chunk沒有代碼變化,生成的hash名和上一次一樣。
filename: 'js/[name].[chunkhash].js', // 格式化字符串
2、配置本地服務(wù),以便開發(fā)環(huán)境
webpack-dev-server 它是基于express、sockjs的一個(gè)node服務(wù)器。全局、本地都安裝。
本地服務(wù)只對(duì)development環(huán)境起作用
3、自動(dòng)清除dist目錄,添加文件hash值,開啟編譯進(jìn)度條、開啟代碼壓縮
自動(dòng)清除dist目錄
v5:output出口配置中添加 clean:true
如果是v4,用 clean-webpack-plugin
添加文件hash值
filename: 'js/[name].[chunkhash].js', // 格式化字符串
開啟編譯進(jìn)度條
plugins中設(shè)置 new webpack.ProgressPlugin()
開啟代碼壓縮
optimization:{ minimize:true, minimizer:[new TerserPlugin()] }
4、區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境。
const common = require('./common')
const build = require('./build')
const serve = require('./serve')
const { merge } =require('webpack-merge')
module.exports = env => merge(common, env.development?serve:build)
mode區(qū)分
5、在當(dāng)前環(huán)境支持圖片的模塊化
v4的寫法
{ test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['url-loader'] },
{ test: /\.(png|jpg|jpeg|gif|webp|svg)$/, use: ['file-loader'] },
v5的寫法
{ test: /\.(png|svg|jpg|jpeg|gif)$/, type: 'asset/resource' },
6、在當(dāng)前環(huán)境中支持樣式的模塊化
css-loader、style-loader、css抽離
處理樣式模塊(v4和v5的寫法是一樣的)
{ test: /\.(css|scss|sass)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },
注意1:當(dāng)同一個(gè)項(xiàng)目中使用sass、less、postcss、stylus等多種css預(yù)處理器時(shí),我們要分別編寫多條樣式模塊的解析規(guī)則。如果只有一種css預(yù)處理器,我們通常把處理.css的loader和處理當(dāng)前這種css預(yù)處理器的loader寫在一起。
[chunkhash] 生成hash字符串的方式:每次打包,webpack根據(jù)當(dāng)前chunk進(jìn)行計(jì)算,如果發(fā)現(xiàn)有代碼變化,就生成新的hash名;如果當(dāng)前chunk沒有代碼變化,生成的hash名和上一次一樣。
注意2:當(dāng)同一條規(guī)則需要多個(gè)loader協(xié)同完成任務(wù)時(shí),要注意loaders的順序,數(shù)組中后面的loader先工作
注意3:一般我們很少使用style-loader,而應(yīng)該使用。。。。把css代碼抽離成樣式的文件。
sass-loader用于加載.scss/.sass文件的,要交給sass編譯器進(jìn)行編譯。(要特別注意node版本、webpack版本和sass-loader版本之間的兼容性)
node v12+ sass-loader v12+ webpack v5
node v12- sass-loader v10- webpack v4
7、把src中的js代碼編譯成瀏覽器能夠普通兼容的ES5代碼
1、第一條規(guī)則:當(dāng)webpack運(yùn)行時(shí),如果遇到以.js為后綴的文件時(shí),webpack就使用babel-loader來加載.js文件,然后交給Babel編譯器(@babel/core、@babel/preset-env)進(jìn)行編譯轉(zhuǎn)換,最終得到ES5代碼。
2、babel-loader 專門用于加載javascript文件,然后交給Babel編譯器進(jìn)行編譯。
裝了一系列的Babel預(yù)設(shè)和插件,添加babel.config.js對(duì)各種Babel包進(jìn)行配置
@babel/core Babel編譯器核心包
@babel/preset-env 用于編譯ES6+代碼
@babel/preset-react 用于編譯jsx代碼
@babel/preset-typesript 用于編譯ts代碼
3、配置預(yù)設(shè)
就是一些比較大的javascript語法版本。預(yù)設(shè)不一定能夠編譯所有的小語法
presets: [
? ? ['@babel/preset-env', {}]
? ],
@babel/core 是Babel編譯器的核心代碼,最新版本 v7
@babel/preset-env 是一個(gè)Babel預(yù)設(shè),用于編譯ES6+語法
@babel/preset-react 是一個(gè)Babel預(yù)設(shè),用于編譯jsx語法
@babel/preset-typescript 是一個(gè)Babel預(yù)設(shè),用于編譯ts語法
4、配置插件
用于彌補(bǔ)預(yù)設(shè)不能編譯的小語法問題
plugins: [
? ? ["@babel/plugin-proposal-decorators", { "legacy": true }],
? ? ["@babel/plugin-proposal-class-properties", {}]
? ]
8、在當(dāng)前環(huán)境中集成ESLint檢測(cè)(集成React開發(fā)環(huán)境的代碼檢測(cè))
1、v4 eslint-loader
exclude 忽略對(duì)某種目錄或文件的檢測(cè)
enforce:'pre' 這條規(guī)則是一條前置規(guī)則,發(fā)生一般規(guī)則之前。只有當(dāng)這條規(guī)則驗(yàn)證通過了,后面的一般規(guī)則才會(huì)運(yùn)行。
eslint-loader 專門用于加載javascript文件,然后交給eslint系列的檢測(cè)工具進(jìn)行檢測(cè)。所以,我們還要安裝很多合適的eslint檢測(cè)工具,并在項(xiàng)目中添加eslint的相關(guān)配置文件。
2、v4 eslint-webpack-plugin 參見.eslintrc.js這個(gè)配置。
3、在v5中,使用eslint-webpack-plugin來配置ESLint,語法是CommonJS語法
意義:協(xié)同開發(fā)保證代碼規(guī)范和一致性。(每個(gè)公司的ESlint規(guī)范不一樣)
ESLint只是一個(gè)javascript代碼檢測(cè)工具,所以根據(jù)不同的項(xiàng)目我們需要安裝不同的ESLint檢測(cè)器(代碼規(guī)范的標(biāo)準(zhǔn))
ESLint的配置文件有六種,當(dāng)前這種是優(yōu)先級(jí)最高的。(.eslint.js文件)
4、如何解決ESLint報(bào)錯(cuò)或警告的問題呢?
1、老老實(shí)實(shí)地找到報(bào)錯(cuò)或警告的地方,把它修復(fù)好。(開發(fā)環(huán)境不便于寫代碼)
2、找到這條ESLint規(guī)則的名稱,在ESLint配置文件中修改它的檢測(cè)級(jí)別
3、使用ESlint注釋包裹代碼,忽略這段代碼的檢測(cè)。
// eslint-disable-line
/* eslint-disable */ /* eslint-enable */
/* eslint-disable no-var */ /* eslint-enable no-var */
4、找到webpack配置文件,把eslint規(guī)則注釋掉。(慎用)
5、在項(xiàng)目的根目錄添加 .eslintigore 這個(gè)文件。(選擇性地忽略某些目錄或文件)
經(jīng)驗(yàn):如果項(xiàng)目老是頻繁報(bào)eslint錯(cuò)誤,建議直接在項(xiàng)目根目錄添加一個(gè).eslintigore文件,選擇性忽略某些代碼的檢測(cè)。當(dāng)提交代碼前,一定要移除.eslintigore文件,重啟項(xiàng)目,修復(fù)所有的eslint問題。(協(xié)同開發(fā)時(shí),切忌把有eslint問題的代碼提交到遠(yuǎn)程)
5、定制React開發(fā)環(huán)境的代碼檢測(cè):
eslint-loader 在webpack v4中集成ESLint
eslint-webpack-plugin 在webpack v5中集成ESlint
eslint 這是ESLint官方提供的基礎(chǔ)檢測(cè)工具,只要使用ESLint必須安裝它
eslint-plugin-react 這是一個(gè)用于檢測(cè)React語法的ESlint插件
eslint-plugin-react-hooks 這是一個(gè)用于檢測(cè)React Hooks語法的ESLint插件
eslint-plugin-jsx-a11y 這是一個(gè)用于檢測(cè)React JSX元素屬性語法的ESLint插件
eslint-plugin-import 這是一個(gè)用于檢測(cè)ES6+模塊化語法的ESLint插件
eslint-config-airbnb 由愛彼迎公司開源的一個(gè)ESLint套件
@babel/eslint-parser 它是Babel-ESlint的前身,可兼容ESLint的默認(rèn)解析器,用于對(duì)比較新的js語法進(jìn)行檢測(cè)。
6、改變eslint規(guī)則的檢測(cè)級(jí)別(三種檢測(cè)級(jí)別)
off (0) -關(guān)閉規(guī)則
warn (1) -違反規(guī)則給警告
error (2) -違反規(guī)則給報(bào)錯(cuò)
9、在當(dāng)前環(huán)境下支持jsx語法
安裝 @babel/preset-react 參見babel.config.js這個(gè)配置。
二、webpack拓展
loader
1、常用loader有哪些?羅列七八個(gè)。
style-loader 將css添加到DOM的內(nèi)聯(lián)樣式標(biāo)簽style里
css-loader 允許將css文件通過require的方式引入,并返回css代碼
less-loader 處理less
sass-loader 處理sass
file-loader 分發(fā)文件到output目錄并返回相對(duì)路徑
url-loader 和file-loader類似,但是當(dāng)文件小于設(shè)定的limit時(shí)可以返回一個(gè)Data Url
html-minify-loader 壓縮HTML
babel-loader 用babel來轉(zhuǎn)換ES6文件到ES5
2、自定義loader
每個(gè)loader都是一個(gè)function函數(shù),它接收一種文件(對(duì)象或字符串),最終返回另外一種文件(對(duì)象、字符串或JS代碼),什么是必須返回JS代碼呢?如果當(dāng)前封裝的loader用于webpack規(guī)則中最后的一個(gè)loader,那么必須返回js代碼。
自定義loader的基本語法:
module.exports = function(source) {
// 使用任何第三方j(luò)s模塊do something
const result = 'some string or object'
// return `module.exports = ${JSON.stringify(result)}`
return `export default ${JSON.stringify(result)}` }
如果一個(gè)loader不用于webpack規(guī)則的最后一個(gè)loader,不要拋出js代碼。
plugin
1、常用plugins有哪些?羅列七八個(gè)。
Html-Webpack-Plugin 在打包結(jié)束后,動(dòng)生成個(gè) html 文件,并把打包生成的js 模塊引到該 html 中
clean-webpack-plugin?刪除(清理)構(gòu)建目錄??
MiniCssExtractPlugin??抽離css文件
ESLintPlugin??代碼檢測(cè)工具
2、自定義plugin
每個(gè)plugin本質(zhì)上都是一個(gè)class類(這個(gè)類必須有一個(gè)叫apply實(shí)例方法,在這個(gè)apply用于向webpack的hooks鉤子上添加一個(gè)事件)。
自定義封裝plugin最重要的是理解什么webpack的hooks鉤子。
舉例:clean-webpack-plugin
優(yōu)化
Wepack開發(fā)環(huán)境優(yōu)化(start)優(yōu)化標(biāo)準(zhǔn):運(yùn)行速度盡量快
1、devtool: 'inline-source-map'(負(fù))
2、watch代碼依賴圖的變化,在v5中hot:true實(shí)現(xiàn)熱更新(正)
3、在開發(fā)環(huán)境中開啟memory緩存(生產(chǎn)環(huán)境下默認(rèn)是關(guān)閉的)(正)
4、在編寫各種loaders規(guī)則或者plugin時(shí),使用exclude、include減少node文件系統(tǒng)的工作。(正)
5、巧用resolve對(duì)各種路徑進(jìn)行優(yōu)化,縮小搜索范圍。(正)
6、使用thread-loader(注意硬件配置)開啟多線程構(gòu)建。(正)
7、使用cache-loader對(duì)“指定文件模塊”進(jìn)行緩存。(正)
8、使用 speed-measure-webpack-plugin 對(duì)所有的plugins進(jìn)行加速。(正)
Webpack生產(chǎn)打包優(yōu)化(build)優(yōu)化標(biāo)準(zhǔn):代碼質(zhì)量優(yōu)化
1、devtool: 'source-map'(正)
2、chunks拆分:
① 在前端代碼中使用“動(dòng)態(tài)導(dǎo)入()=>import()”自動(dòng)實(shí)現(xiàn)代碼分離(正)(推薦)安裝 @babel/plugin-syntax-dynamic-import 支持動(dòng)態(tài)導(dǎo)入語法
② 使用optimization.splitChunks 或 split-chunks-plugin手動(dòng)實(shí)現(xiàn)分離分離(正)(很少用)
3、vendor抽離:在entry入口中對(duì)多個(gè)chunk中重復(fù)的代碼進(jìn)行抽離(正)
4、bundle分析技術(shù):使用webpack-bundle-analyzer對(duì)“代碼依賴圖”進(jìn)行人工分析
5、使用 tree-shaking 技術(shù)把src中的“死代碼”移除掉,以節(jié)省打包后代碼的體積。具體做法是在package.json中添加"sideEffects":false,該功能只對(duì)mode:production起作用。
6、抽離CSS并壓縮:
① 使用 mini-css-extract-plugin 把css代碼抽離出來
② 使用 css-minimizer-webpack-plugin 把css代碼進(jìn)行壓縮
7、terser壓縮:使用 terser-webpack-plugin 集成terser高性能壓縮