目录
2.1 引入 mini-css-extract-plugin
2.2 使用 MiniCssExtractPlugin.loader
3.1 配置 optimization 下的 splitChunks
1. 配置多入口
1.1 entry 配置
// webpack.common.js
entry: {
index: path.join(srcPath, 'index.js'),
other: path.join(srcPath, 'other.js')
},
1.2 生产环境 output 配置
- 打包代码时,加上 hash 戳
- name 即多入口 entry 的 key
- CleanWebpackPlugin 每次打包前,清理之前打包内容
// webpack.prod.js
output: {
// filename: 'bundle.[contentHash:8].js', // 打包代码时,加上 hash 戳
filename: '[name].[contentHash:8].js', // name 即多入口时 entry 的 key
path: distPath,
},
plugins: [
new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
new webpack.DefinePlugin({
// window.ENV = 'production'
ENV: JSON.stringify('production')
})
]
1.3 plugins 入口 html 文件配置
- 生成多个 HtmlWebpackPlugin 实例
- chunks 表示该页面要引用哪些 chunk (即 entry 的 index 和 other),默认全部引用
// webpack.common.js
plugins: [
// new HtmlWebpackPlugin({
// template: path.join(srcPath, 'index.html'),
// filename: 'index.html'
// })
// 多入口 - 生成 index.html
new HtmlWebpackPlugin({
template: path.join(srcPath, 'index.html'),
filename: 'index.html',
// chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),默认全部引用
chunks: ['index'] // 只引用 index.js
}),
// 多入口 - 生成 other.html
new HtmlWebpackPlugin({
template: path.join(srcPath, 'other.html'),
filename: 'other.html',
chunks: ['other'] // 只引用 other.js
})
]
2. 抽离 CSS 文件
- 开发环境下使用 style-loader 通过 <style> 标签注入到页面,没问题
- 生产环境下要抽离并压缩 CSS 文件,不然打包会把 CSS 文件打包到 JS 文件中,体积会比较大。(执行这个 JS 再把 CSS 解析出来,塞到 HTML 中,这样性能并不好)
- mini-css-extract-plugin
2.1 引入 mini-css-extract-plugin
// webpack.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
2.2 使用 MiniCssExtractPlugin.loader
// webpack.prod.js
module: {
rules: [
// 图片 - 考虑 base64 编码的情况
{
test: /\.(png|jpg|jpeg|gif)$/,
use: {
loader: 'url-loader',
options: {
// 小于 5kb 的图片用 base64 格式产出
// 否则,依然延用 file-loader 的形式,产出 url 格式
limit: 5 * 1024,
// 打包到 img 目录下
outputPath: '/img1/',
// 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
// publicPath: 'http://cdn.abc.com'
}
}
},
// 抽离 css
{
test: /\.css$/,
loader: [
MiniCssExtractPlugin.loader, // 注意,这里不再用 style-loader
'css-loader',
'postcss-loader'
]
},
// 抽离 less --> css
{
test: /\.less$/,
loader: [
MiniCssExtractPlugin.loader, // 注意,这里不再用 style-loader
'css-loader',
'less-loader',
'postcss-loader'
]
}
]
},
2.3 抽离 CSS 文件
// webpack.prod.js
plugins: [
new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
new webpack.DefinePlugin({
// window.ENV = 'production'
ENV: JSON.stringify('production')
}),
// 抽离 css 文件
new MiniCssExtractPlugin({
filename: 'css/main.[contentHash:8].css'
})
],
2.4 压缩 CSS 文件
- terser-webpack-plugin
- optimize-css-assets-webpack-plugin
// webpack.prod.js
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
optimization: {
// 压缩 css
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
}
3. 抽离公共代码和第三方代码
- 公共代码:在多入口文件的情况下,如果在每个入口文件中都引入了相同的模块,那么打包时,就会将这个模块重复打包进去,这是没有必要的。
- 第三方代码:每次更改了自己的代码,重新打包,生成了新的 hash 文件名,而第三方包(如lodash)并没有改变,不需要重新打包(使用缓存即可)。
3.1 配置 optimization 下的 splitChunks
chunks 有三个选项值
- initial 入口 chunk,对于异步导入的文件不处理
- async 异步 chunk,只对异步导入的文件处理
- all 全部 chunk
// webpack.prod.js
optimization: {
// 压缩 css
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
// 分割代码块
splitChunks: {
chunks: 'all',
/**
* initial 入口 chunk,对于异步导入的文件不处理
async 异步 chunk,只对异步导入的文件处理
all 全部 chunk
*/
// 缓存分组
cacheGroups: {
// 第三方模块
vendor: {
name: 'vendor', // chunk 名称
priority: 1, // 权限更高,优先抽离,重要!!!
test: /node_modules/,
minSize: 0, // 大小限制,太小就不用单独打包了
minChunks: 1 // 最少复用过几次
},
// 公共的模块
common: {
name: 'common', // chunk 名称
priority: 0, // 优先级
minSize: 0, // 公共模块的大小限制
minChunks: 2 // 公共模块最少复用过几次
}
}
}
}
3.2 配置 HtmlWebpackPlugin 插件
- chunks 表示该页面要引用哪些 chunk,需要哪些引入哪些
// webpack.common.js
plugins: [
// 多入口 - 生成 index.html
new HtmlWebpackPlugin({
template: path.join(srcPath, 'index.html'),
filename: 'index.html',
// chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),默认全部引用
chunks: ['index', 'vendor', 'common'] // 要考虑代码分割
}),
// 多入口 - 生成 other.html
new HtmlWebpackPlugin({
template: path.join(srcPath, 'other.html'),
filename: 'other.html',
chunks: ['other', 'common'] // 考虑代码分割
})
]
4. 懒加载
- import 动态引入,类似 Vue 异步组件
// index.js
// 引入 css
import './style/style1.css'
import './style/style2.less'
import { sum } from './math'
const sumRes = sum(10, 20)
console.log('sumRes', sumRes)
// 引入动态数据 --- 懒加载
setTimeout(() => {
import('./dynamic-data.js').then(res => {
console.log(res.default.message)
})
}, 1500)
5. 处理 JSX
5.1 安装 babel/preset-react
npm install --save-dev @babel/preset-react
5.2 配置 .babelrc
// .babelrc
{
"presets": ["@babel/preset-react"],
"plugins": []
}
5.3 配置 babel-loader 解析 js 语法
// webpack.common.js
module: {
rules: [
{
test: /\.js$/,
loader: ['babel-loader'],
include: srcPath,
exclude: /node_modules/
}
]
},
6. 处理 Vue
6.1 安装 vue-loader
npm install -D vue-loader vue-template-compiler
6.2 配置 vue-loader
module: {
rules: [
{
test: /\.vue$/,
loader: ['vue-loader'],
include: srcPath
}
]
},