webpack5基础用法2
webpack的基础用法2
webpack的优化方向
- 提升开发体验
- 提升打包构建速度
- 减少代码体积
- 优化代码运行性能
SourceMap
生成一个.map文件,形成一个映射, 可以通过错误找到源文件
开发模式: cheap-module-source-map
-
优点: 打包编译速度快, 值包含行映射
-
缺点: 没有映射列
生产模式: source-map
-
优点: 包含行列映射
-
缺点: 打包编译速度更慢
使用
// 开发模式
devtool: 'cheap-module-source-map',
// 模式
mode: 'development'
// 生产模式
devtool: 'source-map',
// 模式
mode: 'production'
HotModuleReplacement (热模块替换)
目前修改文件, 网页会重新加载,因为webpack重新打包了
css里面的style-loader已经实现了热模块替换
js默认不能实现hmr
// 手动实现hmr
if(module.hot) { // 如果支持hmr
module.hot.accept('./js/count')
}
但是在vue中有使用vue-loader实现了hmr, 不需要自己去配置
小结: 不用配置, 默认是开启的, 或手动开启
devServer: {
host: 'localhost', // 服务器域名
port: '3000', // 端口
open: true, // 自动打开浏览器
hot: true
},
OneOf
每一个文件只能被一个rules里面的规则编译,开发模式和生产模式都可以
rules: [
{
oneOf: [
// loader的配置
{
test: /\.css$/, // 只检测css文件
use: [
// 执行顺序: 从右到左, 从上到下
'style-loader', // 将js中的css通过创建style标签的方式添加到html文件中生效
'css-loader' // 将css资源编译成commonjs的模块到js中
]
},
{
test: /\.less$/, // 只检测less文件
// use 可以使用多个loader, loader只能使用一个laoder
use: [
// 执行顺序: 从右到左, 从上到下
'style-loader', // 将js中的css通过创建style标签的方式添加到html文件中生效
'css-loader', // 将css资源编译成commonjs的模块到js中
'less-loader', // 将 less编译成css
]
},
{
test: /\.s[ac]ss$/, // 检测scss或sass
// use 可以使用多个loader, loader只能使用一个laoder
use: [
// 执行顺序: 从右到左, 从上到下
'style-loader', // 将js中的css通过创建style标签的方式添加到html文件中生效
'css-loader', // 将css资源编译成commonjs的模块到js中
'sass-loader', // 将 scssss编译成css
]
},
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: 'asset', // 这个会转base64
parser: {
dataUrlCondition: {
// 小于10kb转base64
// 优点: 请求减少, 缺点: 体积变大
maxSize: 15 * 1024, // 10 kb
}
},
generator: {
// 输出图片名称, hash 更具文件内容生成的hash值 :10 取前10位, ext: 文件的后缀 query 查询
filename: 'static/images/[hash:10][ext][query]'
}
},
{
test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
type: 'asset/resource', // 会原封不动的输出
generator: {
// 输出图片名称, hash 更具文件内容生成的hash值 :10 取前10位, ext: 文件的后缀 query 查询
filename: 'static/media/[hash:10][ext][query]'
}
},
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules里面的js文件
loader: 'babel-loader',
// options: {
// presets: ["@babel/preset-env"]
// }
}
]
}
]
// rules里面的内容剪切, 里面放一个对象, oneOf: [剪切的内容]
Include和Exclude
包含和排除, 只能写一个
用法: loader和plugins里面都能用
// eslint的配置
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, '../src'),
exclude: "node_modules" // 也需要exclude
}),
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules里面的js文件
// include: path.resolve(__dirname, '../src'), // 只处理src下面的文件, 绝对路径,跟上面exclude只能写一个
loader: 'babel-loader',
// options: {
// presets: ["@babel/preset-env"]
// }
}
cache 缓存
对eslint检查 和 babel编译的结果缓存, 加快地二次打包速度
babel:
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules里面的js文件
// include: path.resolve(__dirname, '../src'), // 只处理src下面的文件, 绝对路径,跟上面exclude只能写一个
loader: 'babel-loader',
options: {
// presets: ["@babel/preset-env"],
cacheDirectory: true, // 开启babel缓存
cacheCompression: false, // 关闭缓存压缩
}
}
重新运行后会在node_modules里面生成一个.cache/babel-loader文件
eslint:
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, '../src'),
exclude: "node_modules", // 也需要exclude
cache: true, // 开启缓存
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache')
}),
开启缓存, 创建一个缓存路径, 重新运行后就有生成文件夹了
多进程打包
在特别耗时的任务中使用, 每个进程启动大约为600ms
下载
npm i thread-loader -D
分为 babel, eslint, 和 js压缩
babel:
const os = require('os') // 获取内核
const threads = os.cpus().length // 获取cpu核数
// babel里面使用多进程, 使用use, 添加一个 thread-loader
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules里面的js文件
// loader: 'babel-loader',
use: [
{
loader: 'thread-loader', // 开启多进程
options: {
works: threads // 进程数量
}
},
{
loader: 'babel-loader',
options: {
cacheDirectory: true, // 开启babel缓存
cacheCompression: false, // 关闭缓存压缩
}
}
]
}
eslint
// eslint的配置, 多进程直接添加一个threads就行了
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, '../src'),
exclude: "node_modules", // 也需要exclude
cache: true, // 开启缓存
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'),
threads, // 开启多进程和进程数量
}),
js压缩, 生成模式默认会压缩, 里面用的是内置的 terser 插件
// 引入
const TerserWebpackPlugin = require('terser-webpack-plugin')
// 使用
new TerserWebpackPlugin({
parallel: threads
})
一般压缩可可以放在optimization 里面
optimization: {
minimizer: [
// 压缩css
new cssMinimizerPlugin(),
new TerserWebpackPlugin({
parallel: threads
})
]
},
// 将plugins里面的两项去掉同样可以达到效果
treeshaking
**依赖 es module ** 自动移除无用的代码
webpack默认开启了这个功能 (生产模式)
babel
减少babel生成文件的体积
babel会为编译每个文件都插入辅助代码, 使代码体积过大
babel对一些公共方法使用了非常小的辅助代码, 如 _extend , 默认情况下会被添加到每一个需要它的文件中
可以将这些辅助代码作为一个独立的文件, 来避免重复引入
@babel/plugin-transform-runtime: 禁用了bable自动对每个文件的runtime注入, 而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引入
下载 (开发和生产都可以)
npm i @babel/plugin-transform-runtime -D
使用
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
cacheDirectory: true, // 开启babel缓存
cacheCompression: false, // 关闭缓存压缩
plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
}
}
图片压缩
下载
npm i image-minimizer-webpack-plugin imagemin -D
无损压缩
npm i imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
有损压缩
npm i imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant image-svgo -D
使用 包很难下
// 引入
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
optimization: {
minimizer: [
// 压缩css
new cssMinimizerPlugin(),
// 并行压缩js
new TerserWebpackPlugin({
parallel: threads
}),
// 压缩图片
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: [
['gifsicle', { interlaced: true}],
['jpegtran', { progressive: true}],
['optipng', { optimizationLevel: 5}],
[
'svgo',
{
plugins: [
'preset-default',
'prefixIds',
{
name: 'sortAttrs',
params: {
xmlnsOrder: 'alphabetical'
}
}
]
}
]
]
}
}
})
]
},
code split
代码分割, 按需加载
entry: {
app: './src/app.js',
main: './src/main.js'
},
output: {
path: resolve(__dirname, 'dist'),
filename: '[name].js' // 以文件名自己命名
}
提取公共模块
optimization: {
splitChunks: {
chunks: all, // 对所有模块分割
// 一堆默认值, 按需修改
...
}
}
统一命名
filename: [name].[ext]
chunkFilename: [name].chunk.[ext] // 动态导入的chunk