目錄
1 常用的loader和plugin
2 WebPack多入口配置:
3?如何抽離壓縮css文件
4 webpack如何抽離公共代碼和第三方代碼
?5 webpack如何實現(xiàn)異步加載JS (懶加載)
6? module chunk bundle 的區(qū)別
7??webpack優(yōu)化構(gòu)建速度
hard-source-webpack-plugin
8 webpack 優(yōu)化產(chǎn)出代碼
9 什么是Tree-Shaking
10 ES6 Module和 Commonjs區(qū)別
11什么是 Scope Hosting?
12 babel?
Polyfill
分割線
Webpack構(gòu)建速度優(yōu)化
1??縮小范圍
2 noParse
3 IgnorePlugin
?4 優(yōu)化 resolve 配置
alias
1 常用的loader和plugin
1.? ? file-loader加載文件,url-loader也可以加載文件但是當文件小于闕值轉(zhuǎn)為base64返回,url-loader封裝了file-loader
-
css-loader處理css文件、style-loader將css代碼以style標簽注入到html文件中,less-loader轉(zhuǎn)less文件為css文件
-
postCss-loader轉(zhuǎn)換css文件,例如添加前綴,轉(zhuǎn)換單位
-
babel-loader轉(zhuǎn)es6為es5,轉(zhuǎn)換react語法
-
vue-loader處理vue文件
-
eslint-loader檢查代碼規(guī)范
-
devServer 配置服務(wù)器webpack-dev-server開發(fā)環(huán)境靜態(tài)服務(wù)器(屬性host、port、proxy、contentbase根目錄)
-
devtool配置sourcemap類型
2 WebPack多入口配置:
-
entry需要多入口配置,{chunkname: filePath/file.js}
2 out需要動態(tài)配置[name].hash.js
3 htmlwebpackplugin需要生成多個html(屬性template,fimename,chunks),配置html要引入的chunks
3?如何抽離壓縮css文件
在本地的代碼中可以用style-loader把CSS文件放到style中, 但是線上必須要把CSS進行抽離,壓縮,不然代碼體積很大。 不抽離的CSS文件其實是通過js文件寫入html的style標簽中的 ,這樣要執(zhí)行js才能把css解析出來放入html中,效率很低。 抽離 css 和 less : 注意這里不再使用style-loader,而是使用 MiniCssExtractPlugin.loader 單獨拎出來
1. 抽離:使用miniCssExtratPlugin插件,rules中使用miniCssExtratPlugin.loader替換style-loader,plugin中配置MiniCssExtratPlugin
2. 壓縮:在webpack optimization屬性中配置minmizer,使用optimizeCssAssetsPlugin等工具壓縮css文件去除空格和注釋
webpack5現(xiàn)在一般要使用CssMinimizerPlugin +?MiniCssExtractPlugin,之前的optimize-css-assets-webpack-plugin會報錯
const path = require("path");
const {merge} = require("webpack-merge");
const common = require("./webpack.common");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const {distPath, srcPath} = require("./path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = merge(common, {
mode: "production",
module: {
rules: [
{
test: /\.css$/,
include: srcPath,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
},
{
test: /\.less$/,
include: srcPath,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
}
]
},
output:{
path:distPath,
filename:'bundle.[contenthash:8].js'
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename:'main.[contenthash:8].css'
})
],
optimization:{
minimizer:[
new CssMinimizerPlugin()
]
}
})
4 webpack如何抽離公共代碼和第三方代碼
對應(yīng) html 中引入哪些 js 可以在 HtmlWebpackPlugin 中的 chunks 中 配置
在生產(chǎn)的配置中進行公共代碼和第三方代碼的抽離: 在 optimization 中加 splitChunks
webpack 5好像 chunks 是按需導(dǎo)入了-慕課網(wǎng)
?5 webpack如何實現(xiàn)異步加載JS (懶加載)
1?懶加載使用 import(文件路徑) 函數(shù)來實現(xiàn),返回一個 promise
??import().then(res => res.default)? ?或者 SetTimeout?
2使用 chunk: 入口中的 HtmlWebpackPlugin 插件
6? module chunk bundle 的區(qū)別
module、chunk、bundle的區(qū)別
-
module 一些源代碼,沒有經(jīng)過編譯的,webpack中一切皆模塊
-
chunk 多模塊合成的,如 entry import() splitChunk(下午中間分析部分)
-
bundle 最終輸出的文件
module 是源碼,能引用的都是模塊,不管是什么類型,css、js、圖片等都是模塊,都是源碼 chunk 是多模塊合并成的,中不一定是一個文件,比如 index.js 中還有引入其他的文件 (chunk 是內(nèi)存中的概念,還沒有輸出) bundle 就是最終輸出的文件,一個 chunk 對應(yīng)一個 bundle
7??webpack優(yōu)化構(gòu)建速度
Webpack構(gòu)建速度優(yōu)化_如何提高webpack的構(gòu)建速度_gogo2027的博客-CSDN博客
一、構(gòu)建速度
-
優(yōu)化babel-loader
開啟緩存(開啟cacheDirectory)??use:[babel-loader?cacheDirectory],
include或者exclude明確范圍??eg.include:path.resolve(_dirname,'src')
-
IgnorePlugin
-
noParse
-
happyPack
-
ParallelUglifyPlugin
-
自動刷新
-
熱更新
-
DllPlugin
1、babel-loader es6轉(zhuǎn)到es5 2、IgnorePlugin 避免哪些 ? 3、noParse不去管哪些? 4、happyPack 多進程打包 5、parallelUglifyPlugin 開啟多進程代碼壓縮 6、自動刷新 7、熱更新-瀏覽器不用刷新代碼生效 8、DllPlugin 第三方或者其他比較大的庫事先打包好,作為引用,不用每次重新打包,
-
優(yōu)化babel-loader開啟緩存use:[babel-loader?cacheDirectory],es6代碼沒有改動直接使用緩存不再編譯,指定打包范圍縮小要處理的文件數(shù)量(include/exclude)
-
?ignorePlugin避免引入無用模塊(不引入,可以手動按需引入)
????忽略moment下的/loacle目錄, new webpackPlugin(/\.\/locale/,/moment/)
? ??業(yè)務(wù)代碼中動態(tài)引入需要的語言包,import 'moment/locale/zh-cn'
?3 noParse避免重復(fù)打包(引入,不打包) 已經(jīng)是壓縮過的代碼最小的代碼
區(qū)別: IgnorePlugin 直接不引入,代碼中沒有(自己按需要來引入需要的部分) noParse 引入,但不打包
4?happyPack多進程打包
-
JS單線程,開啟多進程打包
-
提高構(gòu)建速度(特別是多核CPU)
5 ParallelUglifyPlugin 多進程壓縮JS
-
webpack內(nèi)置Uglify工具壓縮js
-
JS單線程,開啟多進程壓縮更快
-
和happyPack同理
關(guān)于開啟多進程
-
項目較大,打包較慢,開啟多進程能提高速度
-
項目較小,打包很快,開啟多進程會降低速度(進程開銷)
-
按需使用
ParallelUglifyPlugin 的配置直接在 plugins 中 new 就可以, new 的時候要給 uglifyJS 傳一些配置
?6??配置熱更新
自動刷新:
一般情況下,如果項目引入了devServer,那么就會默認把熱更新這個功能開啟
?熱更新:
?
?
熱更新是有成本的,要在開發(fā)環(huán)境下自己注冊哪些模塊使用熱更新 這里注冊的范圍是 math.js 文件中的內(nèi)容使用熱更新,回調(diào)函數(shù)部分是熱更新之后執(zhí)行的
在devServer里面配置 hot:true
7? Dllplugin?動態(tài)鏈接庫插件
????DllPlugin(僅為了開發(fā)頻繁打包體驗,用于 dev)
-
前端框架如vue react , 體積大,構(gòu)建慢
-
較穩(wěn)定,不常升級版本
-
同一個版本只構(gòu)建一次即可,不用每次重新構(gòu)建
-
一個庫一個是索引
hard-source-webpack-plugin
hard-source-webpack-plugin 為模塊提供了中間緩存,重復(fù)構(gòu)建時間大約可以減少 80%,但是在?webpack5 中已經(jīng)內(nèi)置了模塊緩存,不需要再使用此插件
生成dll文件 -?Dllplugin
創(chuàng)建一個webpack.dll.js?運行生成dll文件?和mainefest文件
使用dll文件?DllReferencePlugin
index.html中使用dll文件
DllReferencePlugin?指定mainefest文件地址
8 webpack 優(yōu)化產(chǎn)出代碼
-
體積更小
-
合理分包,不重復(fù)加載
-
速度更快,內(nèi)存使用更少
方案
-
小圖片base64格式產(chǎn)出,避免網(wǎng)絡(luò)請求
-
bundle+contenthash
-
懶加載,非核心代碼異步加載
-
提取公共代碼
-
IgnorePlugin減少代碼
-
使用CDN加速,cdn前綴
-
使用production
-
Scope Hosting
9 什么是Tree-Shaking
開啟 prodution 模式之后,就會自動開啟 Tree-Shaking 沒有用到的代碼,在生產(chǎn)打包的時候刪掉就是 tree-shaking 這里的 mult 函數(shù)就是沒用到的代碼,在生產(chǎn)打包時應(yīng)該刪掉
10 ES6 Module和 Commonjs區(qū)別
-
ES6 Module靜態(tài)引入,編譯時引入
-
CommonJs是動態(tài)引入,執(zhí)行時引入(require可以放在if else里)
-
只有ES6 Module才能靜態(tài)分析,實現(xiàn)tree-shaking
CommonJs動態(tài)引入:
?ES6 Module靜態(tài)引入:
11什么是 Scope Hosting?
Scope Hosting
-
把多個函數(shù)(每個模塊可能一個函數(shù))的內(nèi)容,放到一個函數(shù)中
-
代碼體積更小
-
創(chuàng)建函數(shù)作用域更少
-
代碼可讀性更好
12 babel?
babel 環(huán)境搭建和基本配置
Presets/env代表了很多常用的plugin配置,省去很多plugin的配置
?
babel-polyfill是core-js和regenerater的集合
core-js解決不了yield(generate),?regenerater
babel7.4后babel-polyfill已經(jīng)被棄用,推介使用core-js和regenerater
2 babel-polyfill 按需引入
.babelrc:
?babel-runtime
babel-polyfull會污染全局環(huán)境
如何是打包第三方庫,會影響用戶的環(huán)境
babel-runtime? ? : 防止babel-polyfill污染全局環(huán)境Promise等新特性取一個別名如)_promise。需要在.babelrc presets中配置
-
babel/runtime
-
babel/plugin-transform-runtime
前端為何要進行打包和構(gòu)建?
體積更小(Tree-Shaking、壓縮、合并),加載更快
編譯高級語言或語法(TS、ES6+、模塊化、scss)
兼容性和錯誤檢查(Polyfill、postcss、eslint)
統(tǒng)一、高效的開發(fā)環(huán)境
統(tǒng)一的構(gòu)建流程和產(chǎn)出標準
集成公司構(gòu)建規(guī)范(提測、上線等)
module chunk bundle的區(qū)別
module-各個源碼文件,webpack中一切皆模塊
chunk-多模塊合并成的,如entry import()splitChunk
bundle-最終的輸出文件
loader和plugin的區(qū)別
loader模塊轉(zhuǎn)換器,如less->css
plugin擴展插件,如HtmlWebpackPlugin
常見的loader和plugin有哪些
babel和webpack的區(qū)別
babel-JS新語法編譯工具,不關(guān)心模塊化
webpack-打包構(gòu)建工具,是多個loader plugin的集合
如何產(chǎn)出一個lib(第三方的類)
參考webpack.dll.js
output.library
babel-polyfill和babel-runtime的區(qū)別
babel-polyfill會污染全局
babel-runtime不會污染全局
產(chǎn)出第三方lib要用babel-runtime
webpack如何實現(xiàn)懶加載
import()
結(jié)合Vue React異步組件
結(jié)合Vue-router React-router 異步加載路由
為何Proxy不能被Profill?
如Class可以用function模擬
如Promise可以用callback來模擬
但Proxy的功能用Object.defineProperty無法模擬
沒有任何能力能完全模擬出Proxy
Polyfill
Polyfill或者Polyfiller,是英國Web開發(fā)者?Remy Sharp?在咖啡店蹲坑的時候拍腦袋造出來的。當時他想用一個詞來形容"用JavaScript(或者Flash之類的什么鬼)來實現(xiàn)一些瀏覽器不支持的原生API"。Shim這個已經(jīng)有的詞匯第一時間出現(xiàn)在他的腦海里。但是他回頭想了一下Shim一般有自己的API,而不是單純實現(xiàn)原生不支持的API??嗨稼は胍恢毕氩坏胶线m的單詞,于是他一怒之下造了一個單詞Polyfill。除了他自己用這個詞以外,他還給其他開發(fā)者用。隨著他在各種Web會議演講和他寫的書《Introducing HTML5》中頻繁提到這個詞,大家用了都覺得很好,就一起來用。
Polyfill的準確意思為:用于實現(xiàn)瀏覽器并不支持的原生API的代碼。
例如,querySelectorAll是很多現(xiàn)代瀏覽器都支持的原生Web API,但是有些古老的瀏覽器并不支持,那么假設(shè)有人寫了庫,只要用了這個庫, 你就可以在古老的瀏覽器里面使用document.querySelectorAll,使用方法跟現(xiàn)代瀏覽器原生API無異。那么這個庫就可以稱為Polyfill或者Polyfiller。
好,那么問題就來了。jQuery是不是一個Polyfill?答案是No。因為它并不是實現(xiàn)一些標準的原生API,而是封裝了自己API。一個Polyfill是抹平新老瀏覽器?標準原生API?之間的差距的一種封裝,而不是實現(xiàn)自己的API。
已有的一些Polyfill,如?Polymer?是讓舊的瀏覽器也能用上 HTML5 Web Component 的一個Polyfill。FlashCanvas是用Flash實現(xiàn)的可以讓不支持Canvas API的瀏覽器也能用上Canvas的Polyfill。
分割線
---------------------------------------------------------------------------------------------------------------------------------
分割線
Webpack構(gòu)建速度優(yōu)化
- 縮小范圍
- noParse
- IgnorePlugin
- 優(yōu)化 resolve 配置
- externals
- 緩存
1??縮小范圍
在配置 loader 的時候,我們需要更精確的去指定 loader 的作用目錄或者需要排除的目錄,通過使用 include 和 exclude 兩個配置項,可以實現(xiàn)這個功能,常見的例如:
include:符合條件的模塊進行解析
exclude:排除符合條件的模塊,不解析,優(yōu)先級更高
這樣一來,一開始構(gòu)建,我們就能去除一些選項,比如,在使用babel-loader的時候
?
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/react'],
plugins: [[require('@babel/plugin-proposal-decorators'), { legacy: true }]],
cacheDirectory: true, // 啟用緩存
},
},
],
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/,
},
2 noParse
對于我們引入的一些第三方包,比如jQuery
,在這些包內(nèi)部是肯定不會依賴別的包,所以根本不需要webpack去解析它內(nèi)部的依賴關(guān)系,使用 noParse 進行忽略的模塊文件中不會解析?import
、require
?等語法
module:{
noParse:/jquery|lodash/
}
3 IgnorePlugin
有很多的第三方包內(nèi)部會做國際化處理,包含很多的語言包,而這些語言包對我們來說時沒有多大用處的,只會增大包的體積,我們完全可以忽略掉這些語言包,從而提高構(gòu)建效率,減小包的體積。
-
requestRegExp
?表示要忽略的路徑。 -
contextRegExp
?表示要忽略的文件夾目錄。
new webpack.IgnorePlugin({ resourceRegExp, contextRegExp });
//以moment為例,首先找到moment中語言包所在的文件夾,然后在webpack配置文件中添加插件
new webpack.IgnorePlugin(/./locale/, /moment/)
這時候moment使用默認語言英語,如果要使用別的語言,可以手動引入需要使用的語言包。
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-CN')
?4 優(yōu)化 resolve 配置
alias
alias 用的創(chuàng)建?import
?或?require
?的別名,用來簡化模塊引用,項目中基本都需要進行配置。
const path = require('path')
{
...
resolve:{
// 配置別名
alias: {
'~': resolve('src'),
'@': resolve('src'),
'components': resolve('src/components'),
}
}
}
配置完成之后,我們在項目中就可以文章來源:http://www.zghlxwxcb.cn/news/detail-670717.html
// 使用 src 別名 ~
import '~/fonts/iconfont.css'
// 使用 src 別名 @
import '@/fonts/iconfont.css'
配合上noParse,在使用的時候,就無須在構(gòu)建一遍react文章來源地址http://www.zghlxwxcb.cn/news/detail-670717.html
到了這里,關(guān)于WebPack優(yōu)化 Webpack構(gòu)建速度優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!