15.Source Map(12中)
生成bundle.js.map文件,调试源代码
devtool: 'source-map',
// eval模式下的source-map 只知道文件名称
// eval('console.log(123)')
devtool: 'eval',
devtool: 'eval',
const HtmlWebpackPlugin = require('html-webpack-plugin')
const allModes = [
'eval',
'cheap-eval-source-map',
'cheap-module-eval-source-map',
'eval-source-map',
'cheap-source-map',
'cheap-module-source-map',
'inline-cheap-source-map',
'inline-cheap-module-source-map',
'source-map',
'inline-source-map',
'hidden-source-map',
'nosources-source-map'
]
module.exports = allModes.map(item => {
return {
devtool: item,
mode: 'none',
entry: './src/main.js',
output: {
filename: `js/${item}.js`
},
module: {
rules: [
{
test: /.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: `${item}.html`
})
]
}
})
16.选择合适的source-map
// 开发环境 'cheap-eval-source-map',
// 生产环境 'nosources-source-map'
17.Webpack 自动刷新问题
// 编辑器文本自动刷新
18.Webpack HMR体验(Hot Module Replacement)模块热替换(热拔插)
webpack最强大的功能之一
热替换只将修改的模块实时替换到应用中,不必完全刷新应用
// 开启HMR
const webpack = require('webpack')
devServer: {
hot: true, // css可以热替换js不行(脚手架可以内部集成了HMR方案)
}
plugins: [
new webpack.HotModuleReplacementPlugin()
]
19.Webpack使用HMR API
// 入口文件main.js editor模块
const editor = createEditor()
document.body.appendChild(editor)
const img = new Image()
img.src = background
document.body.appendChild(img)
// ============ 以下用于处理 HMR,与业务代码无关 ============
// console.log(createEditor)
let lastEditor = editor
module.hot.accept('./editor', () => {
// console.log('editor 模块更新了,需要这里手动处理热替换逻辑')
// console.log(createEditor)
const value = lastEditor.innerHTML
document.body.removeChild(lastEditor)
const newEditor = createEditor()
newEditor.innerHTML = value
document.body.appendChild(newEditor)
lastEditor = newEditor
})
20.Webpack处理图片模块热替换
import background from './better.png'
const img = new Image()
img.src = background
document.body.appendChild(img)
module.hot.accept('./better.png', () => {
img.src = background // 修改图片后图片文件名会发生变化
console.log(background)
})
21.Webpack HMR注意事项
- 处理HMR的代码报错会导致自动刷新
devServer: {
hotOnly: true
// 只使用 HMR,不会 fallback 到 live reloading,处理HMR的代码报错就不会导致自动刷新
},
- 不使用new webpack.HotModuleReplacementPlugin()会报错
if (module.hot) { // 添加判断
let lastEditor = editor
module.hot.accept('./editor', () => {
const value = lastEditor.innerHTML
document.body.removeChild(lastEditor)
const newEditor = createEditor()
newEditor.innerHTML = value
document.body.appendChild(newEditor)
lastEditor = newEditor
})
module.hot.accept('./better.png', () => {
img.src = background
console.log(background)
})
}
- 代码中有很多与业务无关的代码
分包
chunkIds: 'natural'
当前文件的名称是按自然数进行编号排序,如果某个文件不再被依赖,那么重新打包序号都会变
不利于浏览器缓存
optimization: {
chunkIds: 'deterministic'
}
output: {
chunkFileName: 'js/chunk_[name].js'
}
// 魔法注释
/* webpackChunkName */
runtimeChunk优化配置
依赖单独抽离,记录import加载和解析的规则
runtimeChunk: true // 有利于浏览器长期缓存
output: {
fileName: 'js/[name].[contenthash: 8].bundle.js'
}
runtimeChunk: "single" // 把公共的依赖抽取到一个文件
代码懒加载
// 可能产生等待
import('./index.js')
预获取/预加载prefetch和preload
prefetch浏览器空闲时加载
preload立即加载
// 代码懒加载可能产生等待
import(
/*webpackChunkName: 'title'*/
/*webpackPrefetch: true*/
'./title.js')
import(
/*webpackChunkName: 'title'*/
/* webpackPreload: true */
'./title.js')
第三方扩展设置CDN
output: {
publicPath: 'http://aaa/cdn' // 自己的服务器
}
// 外部依赖不需打包
externals: {
lodash: '_'
}
// index.html
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
inlineChunkHtmlPlugin
向页面注入内容
const inlineChunkHtmlPlugin = require('inline-chunk-html-plugin')
const htmlWebpackPlugin = require('html-webpack-plugin')
new inlineChunkHtmlPlugin(htmlWebpackPlugin, [/runtime.*.js/])
webpack打包Library
打包库文件
output: {
libraryTarget: 'umd',
library: 'syUtil', // 使用,暴露方法名
globalObject: 'this'
}
打包时间和内容分析
speed-measure-webpack-plugin
// Change your webpack config from
const webpackConfig = {
plugins: [new MyPlugin(), new MyOtherPlugin()],
};
// to
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const webpackConfig = smp.wrap({
plugins: [new MyPlugin(), new MyOtherPlugin()],
});
webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
\