webpack打包生成的map文件_从这十几个方面优化你的 Webpack 配置
目錄
開發(fā)環(huán)境性能優(yōu)化
- 優(yōu)化打包構(gòu)建速度
- HMR
- 優(yōu)化代碼調(diào)試
- source-map
HMR
?概念:「HMR:」 hot module replacement 熱模塊替換 / 模塊熱替換
?作用:一個模塊發(fā)生變化,只會重新打包這一個模塊,而不是打包所有模塊,極大的提升了構(gòu)建速度
解決:修改 「entry」 入口,將 html 文件引入
// 引入html,解決熱更新的問題
entry: ['./src/js/index.js', './src/index.html'],
devServer: {
// 開啟 HMR 功能
// 當(dāng)修改了 webpack 配置,新配置要想生效,必須重啟服務(wù)
hot: true
}
}
source-map
?概念:一種提供源代碼構(gòu)建后代碼映射技術(shù)(如果構(gòu)建后代碼出錯了,可以通過映射追蹤到源代碼錯誤)
?- 參數(shù):[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
- source-map:外部(錯誤代碼的準(zhǔn)確信息 和 位置)
- inline-source-map:內(nèi)聯(lián)(只生成一個內(nèi)聯(lián) source-map)(錯誤代碼的準(zhǔn)確信息 和 位置)
- hidden-source-map:外部(直接生成 .map 文件)(不能追蹤源代碼錯誤,只能提示到構(gòu)建后代碼的錯誤位置)
- eval-source-map:內(nèi)聯(lián)(每一個文件都生成對應(yīng)的 source-map,都在 eval)(錯誤代碼的準(zhǔn)確信息 和 位置)
- nosources-source-map:外部(錯誤代碼的準(zhǔn)確信息,沒有源代碼信息)
- cheap-source-map:外部(錯誤代碼的準(zhǔn)確信息 和 位置,但只能精確到行)
- cheap-module-source-map:外部(錯誤代碼的準(zhǔn)確信息 和 位置,會將 loader 的 source-map 加入)
- 開發(fā)環(huán)境:速度快,調(diào)試更友好。eval-source-map / eval-cheap-module-source-map
(vue 和 react 腳手架中默認(rèn)使用:eval-source-map)- 速度快:(eval > inline > cheap > ...)eval-cheap-source-map、eval-source-map、
- 調(diào)試友好:source-map、cheap-module-source-map、cheap-source-map
- 生產(chǎn)環(huán)境:源代碼要不要隱藏?調(diào)試要不要更友好?source-map / cheap-module-source-map
內(nèi)聯(lián)會讓代碼體積變大,所以在生產(chǎn)環(huán)境中只會只用 「外部 source-map」nosources-source-map、hidden-source-map
mode: 'development', // 'production'
devtool: 'eval-source-map' // 'source-map'
}
生產(chǎn)環(huán)境性能優(yōu)化
- 優(yōu)化打包構(gòu)建速度
- oneOf
- babel 緩存
- 多進(jìn)程打包
- externals
- dll
- 優(yōu)化代碼運行的性能
- 緩存(hash -> chunkhash -> contenthash)
- tree shaking
- code split
- 懶加載/預(yù)加載
- PWA
oneOf
?oneOf:避免了每一個文件都要被 loader 過一次 注:不能有兩個配置處理同一種類型文件
?module.exports = {module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
//優(yōu)先執(zhí)行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
// 以下 loader 只會匹配一個
oneOf: [
...,
{},
{}
]
}
]
}
}
cache(緩存)
讓第二次打包構(gòu)建速度更快
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
// 開啟 babel 緩存
// 第二次構(gòu)建時,會讀取之前的緩存
cacheDirectory: true
}
}
]
}
}
讓代碼上線運行緩存更好使用
- hash:每次 webpack 構(gòu)建時會生成一個唯一的 hash 值
問題:因為 js 和 css 是同時使用一個 hash 值(如果重新打包會導(dǎo)致所有文件緩存都失效) - chunkhash:根據(jù) chunk 生成 hash 值。如果打包來源于同一個 chunk,那么 hash 值就一樣
問題:js 和 css 的 hash 值還是一樣的
因為 css 是在 js 文件中被引入的,所以同屬于一個 chunk - 「contenthash」:根據(jù)文件的內(nèi)容生成 hash 值。不同文件的 hash 值移動不一樣
tree shaking(搖樹)
?tree shaking:去除無用的代碼
?前提:1. 必須使用 ES6 模塊化;2. 開啟 production 環(huán)境
作用:減少代碼體積
在 package.json 中配置:
- "sideEffects": false 所有的代碼都沒有副作用(都可以進(jìn)行 tree shaking)
問題:可能會把 css / @babel/polyfill (副作用)文件干掉 - sideEffects: ["*.css", "*.less"]
code split(代碼分割)
entry: {
// 多入口
main: './src/js/index.js',
test: './src/js/test.js'
},
output: {
// [name]: 取文件名
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
mode: 'production'
}
entry: './src/js/index.js',,
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build')
},
// 可以將 node_modules 中的代碼單獨打包一個chunk最終輸出
optimization: {
splitChunks: {
chunks: 'all'
}
}
mode: 'production'
}
// 此處的注釋可以命名打包后文件名
import(/* webpackChunkName: 'test' */ './test.js')
.then(() => {})
.catch(() => {})
懶加載 和 預(yù)加載
?懶加載:當(dāng)文件需要時才加載
??預(yù)加載 prefetch:會在使用前,提前加載 js 文件。等其他資源加載完畢,瀏覽器空閑了,在偷偷加載資源
??正常加載可以認(rèn)為是并行加載(同一時間加載多個文件)
?// import動態(tài)導(dǎo)入語法:能將某個文件單獨打包成一個 chunk// webpackChunkName 此處的注釋可以命名打包后文件名,webpackPrefetch 預(yù)加載
import(/* webpackChunkName: 'test', webpackPrefetch: true */ './test.js')
.then(() => {})
.catch(() => {})
PWA
?PWA:漸進(jìn)式網(wǎng)絡(luò)開發(fā)應(yīng)用程序(離線可訪問)
?插件:workbox --> npm i workbox-webpack-plugin -D
module.exports = {plugins: [
new WorkboxWebpackPlugin.GenerateSW({
// 1. 幫助 serviceworker 快速啟動
// 2. 刪除舊的 serviceworker
// 生成一個 serviceworker 配置文件
clientsClaim: true,
skipWaiting: true
})
]
}
注冊 serviceworker,并處理兼容性問題
解決:需要修改 package.json 中 eslintConfig 配置
"browser": true
}
if ('serviceworker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceworker
.register('/service-worker.js')
.then(() => {
console.log('sw注冊成功了')
})
.catch(() => {
console.log('sw注冊失敗了')
})
})
}
多進(jìn)程打包
插件:npm i thread-loader -D
進(jìn)程啟動大概為 600ms,進(jìn)程通信也有開銷。只有工作消耗品時間比較長,才需要多進(jìn)程打包。
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
// 開啟多進(jìn)程打包
'thread-loader',
{
loader: 'babel-loader',
options: {
presets: []
}
}
]
}
]
}
}
externals
externals: {
// 忽略庫名 --> npm包名
jquery: 'jQuery'
}
}
dll
對代碼進(jìn)行單獨打包,(第三方庫:jQuery,react,vue ...),第二次以后打包時不再打包第三方庫。webpack.dll.js 文件:
注:運行 webpack 時,默認(rèn)查找 webpack.config.js,需要運行 webpack.dll.js 文件時,可以通過運行 webpack --config webpack.dll.js 實現(xiàn)運行
const webpack = require('webpack')
module.exports = {
entry: {
// 最終打包生成的[name] --> jquery
// ['jquery'] --> 要打包的庫是 jquery
jquery: ['jquery']
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dll'),
library: '[name]_[hash]' // 打包的庫里面向外暴露的內(nèi)容的名字
},
plugins: [
// 打包生成一個 manifest.json --> 提供和 jQuery 映射
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射庫的暴露的內(nèi)容名稱
path: resolve(__dirname, 'dll/manifest.json')
})
],
mode: 'produciton'
}
const { resolve } = require('path')
const webpack = require('webpack')
module.exports = {
plugins: [
// 告訴webpack哪些庫不參與打包,同時使用名稱改變
new webpack.DllReferencePlugin({
path: resolve(__dirname, 'dll/manifest.json')
}),
// 將某個文件打包輸出,并在html中自動引入
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
],
mode: 'produciton'
}
◆?◆?◆ ?◆?◆
你的在看我當(dāng)成喜歡總結(jié)
以上是生活随笔為你收集整理的webpack打包生成的map文件_从这十几个方面优化你的 Webpack 配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三十二楼层选几层最好_楼房哪些楼层不能选
- 下一篇: nacos 公共_Springboot,