本note是基于webpack4.0的相关内容。
注意:安装包时最好按照笔记所记录的版本进行安装,避免出现难以预估的bug。
官方参考文档:webpack4.0中文文档
一、webpack简介
1.webpack是什么
webpack是一种前端资源构建工具,一个静态模块打包器(module bundler)。在webpack看来,前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。
2.webpack的五个核心概念
1.入口Entry
入口(Entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图。
2.输出Output
输出(Output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名。
3.Loader
Loader让webpack能够去处理那些非JavaScript文件(webpack自身只理解JavaScript)
4.插件Plugins
插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
5.模式Mode
模式(Mode)指示webpack使用相应模式的配置。
简而言之,开发环境各种注释,日志,调试功能全面;而生产环境由于已经开发完毕,把不要的都去掉,轻装上阵
选项 | 描述 | 特点 |
---|---|---|
development | 开发模式 | 能让代码本地调试运行的环境 |
production | 生产模式 | 能让代码优化上线运行的环境 |
二、webpack初体验
1. 初始化配置
1.初始化package.json
输入指令:npm init
2.下载并安装webpack
输入指令:
npm install webpack@4.41.6 webpack-cli@3.3.11 -g
npm install webpack@4.41.6 webpack-cli@3.3.11 -D
2. 编译打包应用
1.创建文件
2.运行指令
开发环境指令:webpack ./src/index.js -o build/js/built.js --mode=development
功能:webpack能够编译打包js和json文件,并且能够将es6的模块化语法转换成浏览器能识别的语法。
生产环境指令:webpack ./src/index.js -o ./build/built.js --mode=production
功能:在开发配置功能上多一个功能,压缩代码。
注意:webpack编译打包应用的格式是:
webpack 要打包的文件路径 -o 打包完成的文件存放的路径 --mode=整体打包环境
打包环境有两种:1.开发环境 2.生产环境
3.结论
webpack能够编译打包js和json文件。
能将 es6 的模块化语法转换成浏览器能识别的语法。
能压缩代码。
4.webpack存在的问题
不能编译打包 css、img 等文件。
不能将 js 的 es6 基本语法转化为 es5 以下语法。
三、webpack开发环境的基本配置
1. 创建配置文件
1.创建文件webpack.config.js
2.配置代码如下:
const { resolve } = require('path') // node内置核心模块,用来处理路径问题
module.exports = {
entry: './src/js/index.js', // 入口文件
output: { // 输出配置
filename: './built.js', // 输出文件名
path: resolve(__dirname, 'build/js') // 输出文件的路径
// __dirname 表示当前文件所在的位置路径(不包括当前文件)
},
mode: 'development' // 开发环境
}
3.运行指令:webpack
4.结论:此时功能与上节一致。
2. 打包样式(css、less)资源
1.创建文件
2.下载安装loader包:npm i css-loader@3.4.2 style-loader@1.1.3 less-loader@5.0.0 less@3.11.1 -D
3.修改配置文件webpack.config.js
const { resolve } = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
// loader 的配置
module: {
rules: [
// 详细 loader 配置
// 不同文件必须配置 loader 处理
{
// 匹配css文件
test: /\.css$/, // 使用了正则表达式匹配.css为后缀的文件
// 使用哪些loader进行处理
use: [
// 创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效
'style-loader',
// 将 css 文件 变成 commonjs 模块加载 js 中,里面的内容是样式字符串
'css-loader'
]
},
{
// 匹配less文件
test: /\.less$/, // 使用了正则表达式匹配.less为后缀的文件
// 使用哪些loader进行处理
use: [
'style-loader',
'css-loader',
// 将 less 文件编译成 css 文件
// 需要下载 less-loader 和 less
'less-loader'
]
},
]
},
mode: 'development'
}
注意:use 数组中 loader 执行顺序:从右到左,从下到上,依次执行
4.运行指令:webpack
3. 打包HTML资源
1.创建文件
2.下载安装 plugin 包:npm install --save-dev html-webpack-plugin
3.修改配置文件webpack.config.js
const { resolve } = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader 的配置
]
},
plugins: [
// plugins 的配置
// html-webpack-plugin
// 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
// 需求:需要有结构的HTML文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出所有资源(JS/CSS)
template: './src/index.html'
})
],
mode: 'development'
}
4.运行指令:webpack
4. 打包图片资源
1.创建文件
2.下载安装loader包
npm i url-loader@3.0.0 file-loader@5.0.2 -D
3.修改配置文件webpack.config.js
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 入口文件
entry: "./src/index.js",
output: {
filename: "built.js",
path: resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多个loader处理用use
use: ["style-loader", "css-loader", "less-loader"],
},
{
// 处理图片资源
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// npm i url-loader@3.0.0 file-loader@5.0.2 -D
loader: "url-loader",
options: {
// 图片大小小于64kb,就会被base64处理
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 64 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是CommonJS
// 解析时会出问题:[object Module]
// 解决:关闭url-loader的es6模块化,使用CommonJS解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: "[hash:10].[ext]",
},
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: "html-loader",
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
],
mode: "development",
};
4.运行指令webpack
5. 打包其他资源
1.创建文件
2.修改配置文件webpack.config.js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除css/js/html资源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
3.运行指令webpack
6. devserver
1.什么是开发服务器devServer?
开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~),类似于Node中的nodemon插件
特点:只会在内存中编译打包,不会有任何输出
启动devServer指令为:webpack-dev-server
2.安装devServer:npm i webpack-dev-server@3.10.3 -D
3.修改配置文件webpack.config.js
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
...
devServer: {
// 项目构建后的路径
contentBase: resolve(__dirname, "build"),
// 启动gzip压缩,可以减少所占内存(可选参数)
compress: true,
// 设置服务器端口号,输入网址localhost:8080即可查看打包程序
port: 8080,
// 自动打开浏览器(可选参数)
open: true,
},
}
4.运行开发者服务devserver:npx webpack-dev-server
运行成功会得到类似如下的结果:
6. 开发者环境配置
开发者环境配置是基于上述内容的整合
配置文件webpack.config.js
示例代码如下:
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "built.js",
path: resolve(__dirname, "build"),
},
module: {
rules: [
{
// 处理less资源
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
{
// 处理css资源
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
// 处理图片资源
test: /\.(jpg|png|gif)$/,
loader: "url-loader",
options: {
limit: 20 * 1024,
name: "[hash:10].[ext]",
// 关闭es6模块化
esModule: false,
// 图片资源输出路径
outputPath: "imgs",
},
},
{
// 处理html中img资源
test: /\.html$/,
loader: "html-loader",
},
{
// 处理其他资源
exclude: /\.(html|js|css|less|jpg|png|gif)$/,
loader: "file-loader",
options: {
name: "[hash:10].[ext]",
// 其他资源输出目录
outputPath: "media",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
],
mode: "development",
devServer: {
contentBase: resolve(__dirname, "build"),
compress: true,
port: 3000,
open: true,
},
};
四、webpack生产环境的基本配置
1.提取css成单独文件
1.创建文件
2.下载插件:npm i mini-css-extract-plugin@0.9.0 -D
3.修改配置文件webpack.config.js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
// 创建 style 标签,将样式放入
// 'style-loader',
// 这个 loader 取代 style-loader。作用:提取 js 中的 css 成单独文件 MiniCssExtractPlugin.loader,
// 将 css 文件整合到 js 文件中
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
// 对输出的 css 文件进行重命名
filename: 'css/built.css'
})
],
mode: 'development'
};
4.运行指令:webpack
2. css兼容性处理
为什么会出现CSS的兼容性问题?
原因:不同的浏览器使用的内核不一样,对css的解析不一样,所以效果也不一样
1.创建文件
2.下载loader:npm i postcss-loader@3.0.0 postcss-preset-env@6.7.0 -D
3.修改配置文件webpack.config.js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 设置 nodejs 环境变量
// process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss 的插件
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css'
})
],
mode: 'development'
};
4.修改package.json
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
3. 压缩css
1.创建文件
2.下载安装包:npm i optimize-css-assets-webpack-plugin@5.0.3 -D
3.修改配置文件webpack.config.js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin' )
// 设置 nodejs 环境变量
// process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss 的插件
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
// 压缩 css
new OptimizeCssAssetsWebpackPlugin()
],
mode: 'development'
};
4.运行指令:webpack
4. js语法检查
略
5. js兼容性处理
略
6. js压缩
略
7. HTML压缩
略
8. 生产环境配置
略
参考课程:尚硅谷新版webpack实战教程
五、webpack优化配置
webpack优化配置大致可划分为:
- 开发环境性能优化
- 生产环境性能优化
其中开发环境性能优化可划分为:
- 优化打包构建速度
- 优化代码调试
生产环境性能优化:
- 优化打包构建速度
- 优化代码运行的性能
1. HMR
HMR:hot module replacement 热模块替换 / 模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)
有点:极大提升构建速度
其中:
样式文件:可以使用HMT功能,因为style-loader内部实现了
js文件:默认不能使用HMR功能 --> 需要修改js代码,添加支持HMR功能的代码
注意:HMR功能对js的处理,只能处理非入口js文件的其他文件
html文件:默认不能使用HMR功能,同时会导致问题:html文件不能热更新了~(不用做HMR功能)
解决:修改entry入口文件,将html文件引入
entry: ["./src/js/index.js", "./src/index.html"],
开启热模块替换优化:
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
...
...
devServer: {
contentBase: resolve(__dirname, "build"),
compress: true,
port: 3000,
open: true,
// 开启HMR功能
// 当修改了webpack配置,新配置要想生效,必须重启webpack服务
hot: true,
},
}
重启webpack服务:npx webpack-dev-server
当修改样式文件和js文件控制台将显示热模块替换的相关信息。
2. source-map
source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
/*
source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
source-map:外部
错误代码准确信息 和 源代码的错误位置
inline-source-map:内联
只生成一个内联source-map
错误代码准确信息 和 源代码的错误位置
hidden-source-map:外部
错误代码错误原因,但是没有错误位置
不能追踪源代码错误,只能提示到构建后代码的错误位置
eval-source-map:内联
每一个文件都生成对应的source-map,都在eval
错误代码准确信息 和 源代码的错误位置
nosources-source-map:外部
错误代码准确信息, 但是没有任何源代码信息
cheap-source-map:外部
错误代码准确信息 和 源代码的错误位置
只能精确的行
cheap-module-source-map:外部
错误代码准确信息 和 源代码的错误位置
module会将loader的source map加入
内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快
开发环境:速度快,调试更友好
速度快(eval>inline>cheap>...)
eval-cheap-souce-map
eval-source-map
调试更友好
souce-map
cheap-module-souce-map
cheap-souce-map
--> eval-source-map / eval-cheap-module-souce-map
生产环境:源代码要不要隐藏? 调试要不要更友好
内联会让代码体积变大,所以在生产环境不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
--> source-map / cheap-module-souce-map
*/
如何使用source-map?
devServer: {
contentBase: resolve(__dirname, "build"),
compress: true,
port: 3000,
open: true,
// 开启HMR功能
// 当修改了webpack配置,新配置要想生效,必须重启webpack服务
hot: true,
},
devtool: "source-map",
}
3. oneOf
oneOf:用于提升loader的匹配速度,将loader中的匹配规格放入oneOf数组中,当成功匹配到对应文件规则的loader时,不会再向下匹配。
注意:不能有两个配置处理同一种类型文件
实例代码:
module: {
rules: [
{
test: /\.js$/, // oneOf中有另一种匹配js文件的loader,因此将此规则提出来另存
exclude: /node_modules/,
// 优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
// 以下loader只会匹配一个
// 注意:不能有两个配置处理同一种类型文件
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
/*
正常来讲,一个文件只能被一个loader处理。
当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
先执行eslint 在执行babel
*/
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {version: 3},
targets: {
chrome: '60',
firefox: '50'
}
}
]
]
}
},
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
}
]
},
4. tree shaking
tree shaking:去除无用代码
前提:1.必须使用ES6模块化 2.开启production环境
作用:减少代码体积
在package.json中配置
// 所有代码都没有副作用(都可以进行tree shaking)
"sideEffects": false
// 存在问题:可能会把css / @babel/polyfill(副作用)文件干掉
// 解决
"sideEffects": ["*.css", "*.less"]
5. code split
略
6. 懒加载
略
7. pwa
略
8. 多进程打包
略
9. externals
略
10. dll
略
六、webpack配置详解
1. entry详解
/*
entry: 入口起点
1. string --> './src/index.js'
单入口
打包形成一个chunk。 输出一个bundle文件。
此时chunk的名称默认是 main
2. array --> ['./src/index.js', './src/add.js']
多入口
所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
--> 只有在HMR功能中让html热更新生效~
3. object -->
{
index: './src/index.js',
add: './src/add.js'
}
打包输出 index.js和add.js
多入口
有几个入口文件就形成几个chunk,输出几个bundle文件
此时chunk的名称是 key
--> 特殊用法
{
// 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
index: ['./src/index.js', './src/count.js'],
// 形成一个chunk,输出一个bundle文件。
add: './src/add.js'
}
*/
2. output详解
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
// 文件名称(指定名称+目录)
filename: 'js/[name].js',
// 输出文件目录(将来所有资源输出的公共目录)
path: resolve(__dirname, 'build'),
// 所有资源引入公共路径前缀 --> 'imgs/a.jpg' --> '/imgs/a.jpg'
publicPath: '/',
chunkFilename: 'js/[name]_chunk.js', // 非入口chunk的名称
// library: '[name]', // 整个库向外暴露的变量名
// libraryTarget: 'window' // 变量名添加到哪个上 browser
// libraryTarget: 'global' // 变量名添加到哪个上 node
// libraryTarget: 'commonjs'
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development'
};
3. module详解
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
test: /\.css$/,
// 多个loader用use
use: ['style-loader', 'css-loader']
},
{
test: /\.js$/,
// 排除node_modules下的js文件
exclude: /node_modules/,
// 只检查 src 下的js文件
include: resolve(__dirname, 'src'),
// 优先执行
enforce: 'pre',
// 延后执行
// enforce: 'post',
// 单个loader用loader
loader: 'eslint-loader',
options: {}
},
{
// 以下配置只会生效一个
oneOf: []
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development'
};
4. resolve详解
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development',
// 解析模块的规则
resolve: {
// 配置解析模块路径别名: 优点简写路径 缺点路径没有提示
alias: {
$css: resolve(__dirname, 'src/css'),
// 导入src下的css文件下的index.css就可以写成 import '$css/index.css'
},
// 配置省略文件路径的后缀名
extensions: ['.js', '.json', '.jsx', '.css'],
// 导入src下的css文件下的index.css就可以写成 import '$css/index'
// 告诉 webpack 解析模块是去找哪个目录 快速寻找依赖
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
}
};
5. devServer详解
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
},
devServer: {
// 运行代码的目录
contentBase: resolve(__dirname, 'build'),
// 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload
watchContentBase: true,
watchOptions: {
// 忽略文件
ignored: /node_modules/
},
// 启动gzip压缩
compress: true,
// 端口号
port: 5000,
// 域名
host: 'localhost',
// 自动打开浏览器
open: true,
// 开启HMR功能
hot: true,
// 不要显示启动服务器日志信息
clientLogLevel: 'none',
// 除了一些基本启动信息以外,其他内容都不要显示
quiet: true,
// 如果出错了,不要全屏提示~
overlay: false,
// 服务器代理 --> 解决开发环境跨域问题
proxy: {
// 一旦devServer(5000)服务器接受到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000)
'/api': {
target: 'http://localhost:3000',
// 发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
pathRewrite: {
'^/api': ''
}
}
}
}
};
浏览器和服务器之间是存在跨域的,服务器与服务器之间是不存在跨域的。
浏览器和服务器之间存在跨域是因为,跨域是因为浏览器的同源策略引起的,如果不用浏览器发送请求,就不存在跨域问题。
6. optimization
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin')
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build'),
chunkFilename: 'js/[name].[contenthash:10]_chunk.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'production',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
},
optimization: {
splitChunks: {
chunks: 'all'
// 默认值,可以不写~
/* minSize: 30 * 1024, // 分割的chunk最小为30kb
maxSiza: 0, // 最大没有限制
minChunks: 1, // 要提取的chunk最少被引用1次
maxAsyncRequests: 5, // 按需加载时并行加载的文件的最大数量
maxInitialRequests: 3, // 入口js文件最大并行请求数量
automaticNameDelimiter: '~', // 名称连接符
name: true, // 可以使用命名规则
cacheGroups: {
// 分割chunk的组
// node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
// 满足上面的公共规则,如:大小超过30kb,至少被引用一次。
vendors: {
test: /[\\/]node_modules[\\/]/,
// 优先级
priority: -10
},
default: {
// 要提取的chunk最少被引用2次
minChunks: 2,
// 优先级
priority: -20,
// 如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
reuseExistingChunk: true
}
}*/
},
// 将当前模块的记录其他模块的hash单独打包为一个文件 runtime
// 解决:修改a文件导致b文件的contenthash变化
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},
minimizer: [
// 配置生产环境的压缩方案:js和css
new TerserWebpackPlugin({
// 开启缓存
cache: true,
// 开启多进程打包
parallel: true,
// 启动source-map
sourceMap: true
})
]
}
};