webpack5配置及优化
为什么需要构建工具?
- 转换es6语法(低版本浏览器不支持)
- css前缀自动补全,scss/less预处理器编译
- js/css代码压缩与混淆
- 图片文件的压缩
构建工具有哪些?
- grunt
- gulp
- fis3
- rollup
- parcel
- webpack
- vite
相关概念及配置参考
配置文件
webpack 默认配置⽂件:webpack.config.js
可以通过 webpack --config 指定配置⽂件
module.exports = {
entry: './src/index.js', // 入口文件
output: './dist/bundle.js', // 输出的文件
mode: 'production', // 开发环境
module: {
rules: [ // loader配置
test: /\.txt$/,
use: 'raw-loader'
]
},
plugins: [ // 插件配置
new HtmlwebpackPlugin({
template: './src/index.html'
})
]
}
Entry: 打包入口
单文件入口
module.exports = {
entry: './path/to/my/entry/file.js',
}
多文件入口(多页应用)
module.exports = {
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js',
},
}
output:输出
output⽤来告诉webpack如何将编译后的⽂件输出到磁盘
单文件⼊⼝
module.exports = {
entry: './path/to/my/entry/file.js'
output: {
filename: 'bundle.js’,
path: __dirname + '/dist'
}
};
多文件入口
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name]_[chunkhash:8].js', // 通过占位符确保文件名唯一
path: __dirname + '/dist'
}
};
// 写入到硬盘:./dist/app.js, ./dist/search.js
Loaders:加载器
webpack 开箱即用只支持 JS 和 JSON 两种文件类型,通过 Loaders 去支持其它文 件类型并且把它们转化成有效的模块,并且可以添加到依赖图中。
常⻅的 Loaders 有哪些?
名称 | 描述 |
---|---|
babel-loader | 转换ES6、ES7高级js新特性语法 |
css-loader | 支持.css文件的加载和解析 |
less-loader | 将less文件解析为css |
file-loader | 进行图片、字体的打包 |
raw-loader | 将文件以字符串的形式引入 |
thread-loader | 多进程打包js和css |
loader的用法
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true
}
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.ts$/,
use: 'ts-loader'
},
],
},
};
Plugins: 插件
有些loader处理不了,可以通过插件处理,插件⽤于 bundle ⽂件的优化,资源管理和环境变量注⼊,作⽤于整个构建过程
常⻅的 Plugins 有哪些?
名称 | 描述 |
---|---|
CommonsChunkPlugin | 将chunks相同的模块代码提取为公共的js |
CleanWebpackPlugin | 清理目录插件 |
ExtraTextWebpackPlugin | 将css从bunlde文件提取成一个独立的css文件 |
CopyWebpackPlugin | 将文件或者文件夹拷贝到构建的输出目录 |
HtmlWebpackPlugin | 创建html文件加载输出的bundle文件 |
UglifyjsWebpackPlugin | 压缩js |
Plugins 的⽤法
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 访问内置的插件
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
},
],
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin(
{
template: './src/index.html'
}
),
],
};
Mode: 构建环境
Mode ⽤来指定当前的构建环境是:production、development 还是 none 设置 mode 可以使⽤ webpack 内置的函数,默认值为 production
Externals: 外部扩展
通过script
标签外部链接引入公共库文件,减少打包速度和公共包体积
externals: {
'vue': 'Vue',
'element-ui': 'ELEMENT',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
},
resolve:解析文件解析
resolve: {
// 引入文件时可以不使用后缀
extensions:['.js', '.json', '.vue'],
// 通过别名引入
alias: {
'@images': path.resolve(__dirname, './assets/images'),
'@style': path.resolve(__dirname, './assets/style'),
'@src': path.resolve(__dirname, './src'),
}
}
target:打包输出的目标
v5版本默认打包输出的是带有箭头函数的自执行函数,兼容性不好,需要设置为
// webpack 将生成 web 平台的运行时代码,并且只使用 ES5 相关的特性。
target: [
'web',
'es5'
]
模块热更新
适用于开发环境development
,使用webpack-dev-server
注意webpack v5版本需要安装4.0以前的版本,4.0后的版本去掉了
contentBase
devServer: {
contentBase: path.join(__dirname, './dist'),
host: 'localhost',
port: '9000',
open: true, // 打开浏览器
hot: true, // 启动模块热更新
}
文件的压缩
html压缩
HtmlWebpackPlugin 简化了 HTML 文件的创建
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'), // 模版入口
filename: 'index.html',
chunks: ['main'],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
})
]
};
js压缩与加密
TerserPlugin插件使用 terser 来压缩 JavaScript。
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin()
],
},
};
js加密插件webpack-obfuscator
css压缩
CssMinimizerWebpackPlugin插件使用 cssnano 优化和压缩 CSS。
optimization: {
minimizer: [
new CssMinimizerPlugin({
parallel: true, // 启动多线程压缩
minimizerOptions: {
preset: ["advanced"], // cssnano https://cssnano.co/docs/optimisations/
}
}),
],
},
图片压缩
image-webpack-loader 插件进行压缩
// 解析图片
{
test: /\.(jpg|jpeg|png|gif|svg)$/i,
type: 'asset/resource', // v5 内置模块解析静态资源
generator: {
filename: 'static/images/[contenthash][ext][query]'
},
use: [
// 图片压缩
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
}
css自动添加前缀
PostCSS 插件 autoprefixer ⾃动补⻬ CSS3 前缀 根据 Can I Use 规则( caniuse.com/ )
const autoprefixer = require('autoprefixer')
// 解析scss
{
test: /\.(s[ac]ss|css)$/i,
use: [
MiniCssExtractPlugin.loader
'css-loader',
'sass-loader',
{
loader: 'postcss-loader',
// 也可以提取到到postcss.config.js
options: {
postcssOptions: {
plugins: [
autoprefixer
]
}
}
}
]
}
增加.browserslistrc文件,添加浏览器规则
last 2 version
> 1%
ie > 8
js公共包的分离
splitChunks配置中设置分割规则
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
}
}
}
css文件抽离
MiniCssExtractPlugin插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件。
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
],
},
};
动态按需加载
js懒加载,common.js的require.ensure,es6的动态import(需要babel插件转换)
{
"plugins": ["@babel/plugin-syntax-dynamic-import"],
...
}
tree shaking(摇树优化)
1 个模块可能有多个⽅法,只要其中的某个⽅法使⽤到了,则整个⽂件都会被打到 bundle ⾥⾯去,tree shaking 就是只把⽤到的⽅法打⼊ bundle ,没⽤到的⽅法会在 uglify 阶段被擦除掉。
webpack 默认⽀持,production mode的情况下默认开启
构建优化显示
统计信息 stats 设置成 errors-only
使⽤ friendly-errors-webpack-plugin 插件
plugins: [
new FriendlyErrorsWebpackPlugin()
],
stats: 'errors-only'
多进程/多实例构建
使用官方推荐thread-loader,需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。
请仅在耗时的操作中使用此 loader!
module.exports = {
module: {
rules: [
{
test: /\.js$/,
include: path.resolve('src'),
use: [
"thread-loader",
// 耗时的 loader (例如 babel-loader)
],
},
],
},
};
构建包依赖分析
webpack-bundle-analyzer插件分析体积
转载自:https://juejin.cn/post/7006109696926941221