一、webpack基本
1、webpack构建流程
初始化流程:从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数
编译构建流程:从 Entry 出发,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行 Module 编译处理
输出流程:对编译后的Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统
2、五大核心概念
webpack 五个核心概念:
- 入口(Entry): webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
- 输出(Output): webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
- Loader(加载器): 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
- 插件(Plugins):可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
- 模式(Mode): webpack 使用相应模式的配置。develop模式,production模式,不同的运行环境上线运行。
3、配置及作用
| 配置属性名 | |
|---|---|
| mode | 默认值为development,值为production时,代码会压缩 |
| entry | 打包入口,打包成chunk及入口 |
| output | 打包出口,配置打包位置等信息 |
| plugins | 插件,可以配置打包过程中所用的插件,如HtmlWebpackPlugin、mini-css-extract-plugin |
| module | 模块,配置不同后缀文件打包loader |
| devServer | 开发服务,可以配置打开接口proxy等 |
| optimization | 优化,可以配置抽离公共代码的优化 |
二、常用依赖及作用
| 依赖 | 作用 |
|---|---|
| html-webpack-plugin | 生成html文件,可根据模板生成html文件 |
| webpack-merge | webpack配置合并 |
| mini-css-extract-plugin | css处理抽离压缩 |
| style-loader | css处理,但并未抽离,包含在js中 |
| postcss-loader和autoprefixer | css浏览器兼容,即在各个css添加前缀 |
| file-loader | 图片处理,把图片复制一份放到打包目录下 |
| url-loader | 图片处理,转化为base64 |
| less和less-loader | less处理 |
| webpack-dev-server | webpack dev打包并启动服务器 |
| cross-env | 可以设置环境变量,需要放在webpack前使用 |
| webpack-bundle-analyzer | 打包体积分析 |
| terser-webpack-plugin | js压缩 |
| optimize-css-assets-webpack-plugin | css压缩,适用webpack4 |
| css-minimizer-webpack-plugin | css压缩,适用webpack5 |
三、常用插件配置
1、css插件配置
一般需要style-loader、css-loader,
先处理的插件放在后面,因为插件是链式调用从下到上进行
style-loader把css文件放在style标签里面
使用mini-css-extract-plugin抽离css插件优化css文件大小
mini-css-extract-plugin不支持热更新,所以开发环境请使用style-loader
postcss-loader、autoprefixer添加css前缀,进行浏览器兼容
webpack.js配置
module: {
rules: [
{
test: /.(less|css)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader"
},
{
loader: "postcss-loader"
},
{
loader: "less-loader"
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "index.css" //输出的css文件名,默认以入口文件名命名(例如main.css)
})
]
postcss.config.js配置
module.exports = {
plugins: {
autoprefixer: {
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
]
}
}
};
2、本地图片配置即静态资源配置
一般会用到file-loader,url-loader
file-loader目的是把图片文件复制一份并引用
module: {
rules: [
{
test: /.(jpg)$/,
use: [
'file-loader'
]
}
]
}
url-loader目的是把图片文件转为base64格式引用,减少http请求次数。一般配置最大文件大小,目的是限制文件大小,文件太大不必转化为base64,否则会导致页面白屏时间增长
图片base64格式优点,减少http请求次数,缺点是太大的情况会影响页面首次加载速度。
module: {
rules: [
{
test: /.(jpg|webp)$/,
use: [
{
loader: "url-loader",
options: {
limit: 5 * 1024,
outputPath: "/path/"
}
}
]
}
3、html插件
html-webpack-plugin插件的基本作用就是生成html文件。原理很简单:
将 webpack中entry配置的相关入口chunk 和 extract-text-webpack-plugin抽取的css样式 插入到该插件提供的template或者templateContent配置项指定的内容基础上生成一个html文件, 具体插入方式是将样式link插入到head元素中,script插入到head或者body中。
四、其他功能
1、多入口打包
多入口打包
1、在entry中配置入口,即把入口文件打包成chunk,chunk名称就是键名
entry: {
index: "./page/index.js",
main: "./page/main.js"
},
2、在plugins中添加 new HtmlWebpackPlugin()
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
filename: "index.html",
chunks: ["index"],
title: "index"
}),
new HtmlWebpackPlugin({
template: "./index.html",
filename: "main.html",
chunks: ["main"],
title: "main"
})
]
2、抽离公共代码
1)抽离js公共模块
抽离公共代码只在生产环境使用,开发环境没有必要
webpack在进行抽离公共代码的时候分为两种,一种是公共模块,一种是第三方模块; 对于公共模块:不需要重复打包,抽离成一个单独的公共模块文件,然后引用即可; 对第三方模块:一般不会轻易改变,所以就单独抽离一个第三方模块的文件,引用即可;
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
// 第三方模块
vendors: {
name: "vendor", // 每个组的名字
priority: 1, // 优先级,越小优先级越高
// 检测模块是否来自于node_modules,是否通过npm下载的
test: /[\/]node_modules[\/]/,
// 设置代码分割的最小界限;
// 可以设置成 5 * 1024 大小 5kb
// 大于 5kb 的文件才会做分割,也可以设置为 0
minSize: 5 * 1024,
minChunks: 1 // 检测模块被引用几次就可以单独打包
},
// 公共模块
common: {
name: "common",
priority: 0,
minSize: 0,
minChunks: 2
},
default: {
// 默认设置,可被重写
minChunks: 2,
priority: -20, // 如果本来已经把代码提取出来,则重用存在的而不是重新产生
reuseExistingChunk: true
}
}
}
}
2)抽离css
使用mini-css-extract-plugin进行css抽离
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
{
test: /\.(less)$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"less-loader"
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "./css/index.css"
})
],
}
3、proxy接口代理配置
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: { '^/api': '' },
changeOrigin: true, // 默认保持主机头,true进行覆盖
secure: false, // https上运行
},
},
}
};
4、使用NODE_ENV环境变量
需要使用插件cross-env,eg:
"dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.config.js"
console.log(process.env.NODE_ENV);
5、代码压缩
1)js代码压缩
可以使用terser-webpack-plugin进行压缩,实际上配置 mode: "production"本事就带有js压缩功能,但是terser-webpack-plugin也可以配置其他内容比如去除console.log
2)css代码压缩
optimize-css-assets-webpack-plugin可以压缩webpack4的css
css-minimizer-webpack-plugin可以用来压缩webpack5的css
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
......
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})],
}
......
6、打包体积分析
使用webpack-bundle-analyzer进行打包分析
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
...
plugins: [
new BundleAnalyzerPlugin(),
]
...