第 5 章 Webpack 优化配置
5.1 HMR
1.创建文件
2.修改 webpack.config.js 文件
js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ['./src/index.js', './src/index.html'],
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|jpeg|gif|bmp)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[name]-[hash:8].[ext]',
outputPath: 'images',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|html|less|png|jpg|jpeg|gif|bmp)$/,
loader: 'file-loader',
options: {
name: '[name]-[hash:8].[ext]',
outputPath: 'medias',
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true,
// 开启 HMR 功能
hot: true,
},
};
3.修改 js 文件
js
if (module.hot) {
module.hot.accept('xxx.js', () => {
// do something hmr here
console.log('执行 HRM 代码');
});
}
4.运行指令
bash
npx webpack
5.2 source-map
1.创建文件
2.修改 webpack.config.js 配置文件
js
/*
HMR: hot module replacement 热模块替换/模块热替换
作用:一个模块发生变化,只会重新打包这一个模块,而不是打包所有模块
极大提升构建速度
样式文件:可以使用 HMR 实时更新样式,因为 style-loader 已经内置了 HMR 功能
js 文件:默认没有 HMR 功能 --> 需要修改 js 代码,添加支持 HMR 功能的代码
注意:HMR 功能对 js 文件的处理,只能处理非入口 js 文件的其他文件。
html 文件:默认不支持 HMR,同时会导致问题:html 文件不能支持热更新(不需要热更新)
解决方案:修改 entry 入口,将 html 文件 引入 entry
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// webpack 配置
module.exports = {
// 入口起点
entry: ['./src/index.js', './src/index.html'],
// 输出
output: {
// 输出的文件名
filename: 'js/built.js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
{
// 处理 less 资源
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
// 处理 css 资源
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
// 处理图片资源
test: /\.(png|jpg|jpeg|gif|bmp)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[name]-[hash:8].[ext]',
outputPath: 'images',
// 关闭 es 6 模块化
esModule: false,
},
},
{
// 处理 html 中的图片资源
test: /\.html$/,
loader: 'html-loader',
},
// 打包其他资源 (除了 js、css、html 资源)
{
// 排除 js、css、html 以外的资源
exclude: /\.(js|css|html|less|png|jpg|jpeg|gif|bmp)$/,
loader: 'file-loader',
options: {
name: '[name]-[hash:8].[ext]',
outputPath: 'medias',
},
},
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
}),
],
// 开发模式 'development' | 'production'
mode: 'development',
// 开发服务器 devServer:用来自动化(自动编译、自动打开浏览器、自动刷新浏览器)
// 特点:只会在内存中打包,不会有任何输出
// 启动 devServer 指令为:npx webpack-dev-server
devServer: {
contentBase: resolve(__dirname, 'build'),
// 启用 gzip 压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true,
// 开启 HMR 功能
// 注意:当修改了 webpack 配置,需要重启 devServer
hot: true,
},
devtool: 'eval-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
错误代码的准确信息和源代码的错误位置,错误文件文件名多了 hash 值
nosources-source-map: 外部
错误代码的准确信息,但是没有任何源代码的错误信息
cheap-source-map: 外部
错误代码的准确信息和源代码的错误位置
只能精确到行
cheap-module-source-map: 外部
错误代码的准确信息和源代码的错误位置
module 会将 loader 的 source map 加入
内联与外部的区别:
1.外部生成文件,内联没有
2.内联构建速度更快
开发环境:速度快,调试更友好
速度快(eval > inline > cheap > ...)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map
--> eval-source-map / eval-cheap-module-source-map
生产环境:源代码是否隐藏?调试是否友好
内联会让代码体积变大,所以在生产环境不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
--> source-map / cheap-module-source-map
*/
3.运行指令
bash
npx webpack
5.3 oneOf
1.创建文件
2.修改 webpack.config.js 文件
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');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// 复用 loader 配置
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
// postcss 配置
plugins: [
// postcss-preset-env 插件
require('postcss-preset-env')(),
],
},
},
},
];
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'assets/js/built.js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
/*
正常来讲,一个文件只能被一个 loader 处理
当一个文件被多个 loader 处理时,那么一定要指定 loader 的执行顺序:
先执行 eslint 再处理 babel
*/
{
// 在 package.json 中配置 eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
// 自动修复
fix: true,
},
},
{
// 一下 loader 只会匹配一个
// 注意:不能有两个配置处理同一种类型文件
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
// 基本语法兼容
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定 corejs 的版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' },
},
],
],
},
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[name]-[hash:8].[ext]',
outputPath: 'assets/images',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|less|html|png|jpe?g|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name]-[hash:8].[ext]',
outputPath: 'assets/media',
esModule: false,
},
},
],
},
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
new MiniCssExtractPlugin({
filename: 'assets/css/[name]-[hash:8].css',
}),
new OptimizeCssAssetsWebpackPlugin(),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
5.4 缓存
1.创建文件
2.修改 webpack.config.js 文件
js
/*
缓存:
babel 缓存:
cacheDirectory: true
--> 第二次打包速度更快
文件资源缓存:
hash: 每次 webpack 构建都会生成一个唯一的 hash 值。
问题:因为 js 和 css 同时使用一个 hash 值,如果重新打包,会导致所有缓存失效(可能只改动一个文件)。
chunkhash: 根据 chunk 生成的 hash 值。如果打包来源于同一个 chunk,那么 hash 值也相同。
问题:js 和 css 的 hash 值还是相同的。
因为 css 是在 js 中被引入的,所以同属于一个 chunk
contenthash: 根据文件内容生成的 hash 值,不同文件的 hash 值不同。
--> 让上线代码运行缓存更好用
*/
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');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// 复用 loader 配置
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
// postcss 配置
plugins: [
// postcss-preset-env 插件
require('postcss-preset-env')(),
],
},
},
},
];
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'assets/js/built.[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
/*
正常来讲,一个文件只能被一个 loader 处理
当一个文件被多个 loader 处理时,那么一定要指定 loader 的执行顺序:
先执行 eslint 再处理 babel
*/
{
// 在 package.json 中配置 eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
// 自动修复
fix: true,
},
},
{
// 一下 loader 只会匹配一个
// 注意:不能有两个配置处理同一种类型文件
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
// 基本语法兼容
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定 corejs 的版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' },
},
],
],
// 开启 babel 缓存
// 第二次构建时,会读取缓存,加快构建速度
cacheDirectory: true,
},
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/images',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|less|html|png|jpe?g|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/media',
esModule: false,
},
},
],
},
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
new MiniCssExtractPlugin({
filename: 'assets/css/[name]-[contenthash:8].css',
}),
new OptimizeCssAssetsWebpackPlugin(),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
5.5 tree shaking
1.创建文件
2.修改 webpack.config.js 文件
js
/*
tree shaking: 去除无用的代码
前提:1.必须使用 ES6 模块化语法 2.开启 production 模式
作用:减少代码体积
在 package.json 中配置
"sideEffects": false,表示所有代码都没有副作用,都可以进行 tree shaking
问题:可能会把 css、@babel-/polyfill (副作用)文件都干掉
"sideEffects": ["*.css","*.less"],不会对这些文件进行 tree shaking
*/
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');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// 复用 loader 配置
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
// postcss 配置
plugins: [
// postcss-preset-env 插件
require('postcss-preset-env')(),
],
},
},
},
];
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'assets/js/built.[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
/*
正常来讲,一个文件只能被一个 loader 处理
当一个文件被多个 loader 处理时,那么一定要指定 loader 的执行顺序:
先执行 eslint 再处理 babel
*/
{
// 在 package.json 中配置 eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
// 自动修复
fix: true,
},
},
{
// 一下 loader 只会匹配一个
// 注意:不能有两个配置处理同一种类型文件
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
// 基本语法兼容
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定 corejs 的版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' },
},
],
],
// 开启 babel 缓存
// 第二次构建时,会读取缓存,加快构建速度
cacheDirectory: true,
},
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/images',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|less|html|png|jpe?g|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/media',
esModule: false,
},
},
],
},
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
new MiniCssExtractPlugin({
filename: 'assets/css/[name]-[contenthash:8].css',
}),
new OptimizeCssAssetsWebpackPlugin(),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
5.6 code split
1.创建文件
2.修改 webpack.config.js 文件
第一种
js
/*
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// webpack 配置
module.exports = {
// 单入口
//entry: './src/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个 bundle
main: './src/index.js',
test: './src/js/test.js',
},
// 输出
output: {
// [name]: 取文件名
filename: 'assets/js/[name].[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
第二种
js
/*
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// webpack 配置
module.exports = {
// 单入口
// entry: './src/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个 bundle
main: './src/index.js',
test: './src/js/test.js',
},
// 输出
output: {
// [name]: 取文件名
filename: 'assets/js/[name].[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
],
/*
1. 可以将 node_modules 中的代码单独打包一个 chunk 最终输出
2. 自动分析多入口 chunk 中有没有公共的依赖。如果有会打包成单独一个 chunk
*/
optimization: {
splitChunks: {
chunks: 'all',
},
},
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
第三种
js
/*
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// webpack 配置
module.exports = {
// 单入口
// entry: './src/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个 bundle
main: './src/index.js',
test: './src/js/test.js',
},
// 输出
output: {
// [name]: 取文件名
filename: 'assets/js/[name].[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
],
/*
1. 可以将 node_modules 中的代码单独打包一个 chunk 最终输出
2. 自动分析多入口 chunk 中有没有公共的依赖。如果有会打包成单独一个 chunk
*/
optimization: {
splitChunks: {
chunks: 'all',
},
},
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
5.7 lazy loading
1.创建文件
2.修改 webpack.config.js 文件
js
/*
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// webpack 配置
module.exports = {
// 单入口
//entry: './src/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个 bundle
main: './src/index.js',
test: './src/js/test.js',
},
// 输出
output: {
// [name]: 取文件名
filename: 'assets/js/[name].[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
5.8 PWA
1.创建文件
2.修改 webpack.config.js 文件
js
/*
PWA:Progressive Web App 渐进式网络开发应用程序(离线可访问)
workbox --> workbox-webpack-plugin
*/
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');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// 复用 loader 配置
const commonCssLoader = [
{
loader: MiniCssExtractPlugin.loader,
// fix: 打包后图片路径、字体文件路径错误问题
options: {
publicPath: '../../',
},
},
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
// postcss 配置
plugins: [
// postcss-preset-env 插件
require('postcss-preset-env')(),
],
},
},
},
];
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'assets/js/built.[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
/*
正常来讲,一个文件只能被一个 loader 处理
当一个文件被多个 loader 处理时,那么一定要指定 loader 的执行顺序:
先执行 eslint 再处理 babel
*/
{
// 在 package.json 中配置 eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
// 自动修复
fix: true,
},
},
{
// 一下 loader 只会匹配一个
// 注意:不能有两个配置处理同一种类型文件
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
// 基本语法兼容
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定 corejs 的版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' },
},
],
],
// 开启 babel 缓存
// 第二次构建时,会读取缓存,加快构建速度
cacheDirectory: true,
},
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/images',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|less|html|png|jpe?g|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/media',
esModule: false,
},
},
],
},
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
new MiniCssExtractPlugin({
filename: 'assets/css/[name]-[contenthash:8].css',
}),
new OptimizeCssAssetsWebpackPlugin(),
new WorkboxWebpackPlugin.GenerateSW({
/*
1. 帮助 serviceworker 快速启动
2. 删除旧的 serviceworker
生成一个 serviceworker 配置文件
*/
clientsClaim: true,
skipWaiting: true,
}),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
5.9 多进程打包
1.创建文件
2.修改 webpack.config.js 文件
js
/*
PWA:Progressive Web App 渐进式网络开发应用程序(离线可访问)
workbox --> workbox-webpack-plugin
*/
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');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
// 设置 node 环境变量: 决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';
// 复用 loader 配置
const commonCssLoader = [
{
loader: MiniCssExtractPlugin.loader,
// fix: 打包后图片路径、字体文件路径错误问题
options: {
publicPath: '../../',
},
},
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
// postcss 配置
plugins: [
// postcss-preset-env 插件
require('postcss-preset-env')(),
],
},
},
},
];
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'assets/js/built.[contenthash:10].js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
/*
正常来讲,一个文件只能被一个 loader 处理
当一个文件被多个 loader 处理时,那么一定要指定 loader 的执行顺序:
先执行 eslint 再处理 babel
*/
{
// 在 package.json 中配置 eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
// 优先执行
enforce: 'pre',
options: {
// 自动修复
fix: true,
},
},
{
// 一下 loader 只会匹配一个
// 注意:不能有两个配置处理同一种类型文件
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
/*
开启多线程打包
进程启动大概为 600 ms,进程通信也有开销
只有工作消耗时间较长,才需要多进程打包
*/
{
loader: 'thread-loader',
options: {
workers: 2,
},
},
{
loader: 'babel-loader',
options: {
presets: [
[
// 基本语法兼容
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定 corejs 的版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' },
},
],
],
// 开启 babel 缓存
// 第二次构建时,会读取缓存,加快构建速度
cacheDirectory: true,
},
},
],
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/images',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|less|html|png|jpe?g|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name]-[contenthash:8].[ext]',
outputPath: 'assets/media',
esModule: false,
},
},
],
},
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
// 压缩 html 文件
minify: {
// 压缩 html 文件
removeComments: true, // 移除 HTML 注释
collapseWhitespace: true, // 移除空格
},
}),
new MiniCssExtractPlugin({
filename: 'assets/css/[name]-[contenthash:8].css',
}),
new OptimizeCssAssetsWebpackPlugin(),
new WorkboxWebpackPlugin.GenerateSW({
/*
1. 帮助 serviceworker 快速启动
2. 删除旧的 serviceworker
生成一个 serviceworker 配置文件
*/
clientsClaim: true,
skipWaiting: true,
}),
],
// 开发模式 'development' | 'production'
// 生产环境下,会自动压缩 js 代码
mode: 'production',
};
3.运行指令
bash
npx webpack
5.10 externals
1.创建文件
2.修改 webpack.config.js 文件
js
/*
loader: 1.下载 2.使用(配置 loader)
plugins: 1.下载 2.引入 3.使用
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'js/built.js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
}),
],
// 开发模式 'development' | 'production'
mode: 'production',
externals: {
// 忽略库名-- npm 包名
// 拒绝 jQuery 被打包进 js 文件
jquery: 'jQuery',
},
};
3.运行指令
bash
npx webpack
5.11 dll
1.创建文件
2.修改 webpack.config.js 文件
js
/*
loader: 1.下载 2.使用(配置 loader)
plugins: 1.下载 2.引入 3.使用
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
// webpack 配置
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出的文件名
filename: 'built.js',
// 输出路径
// __dirname nodejs 的全局变量,代表当前文件(webpack.config.js)所在目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细的 loader 配置
],
},
// plugins 的配置
plugins: [
// 插件的配置
// html-webpack-plugin
// 功能:默认会创建一个空的 html 文件,自动引入打包输出的所有资源(js、css等)
// 需求:需要有结构的 html 文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源
template: './src/index.html',
}),
// 告诉 webpack 哪些库不参与打包,同时使用时的名称也得变
new webpack.DllReferencePlugin({
// 动态链接库的 manifest 文件路径
manifest: resolve(__dirname, 'dll/manifest.json'),
}),
// 将某个文件打包输出出去,并在 html 中自动引入
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js'),
}),
],
// 开发模式 'development' | 'production'
mode: 'production',
};
3.创建 webpack.dll.js
js
/*
使用 dll 技术,对某些库(第三方库:jquery、react、vue等)进行单独打包
当你运行 webpack 时,默认查找 webpack.config.js 配置文件
需求:需要运行 webpack.dll.js 文件
--> webpack --config webpack.dll.js
*/
const { resolve } = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
// 最终打包生成的[name] --> jquery
// ['jquery'] --> 要打包的库是 jquery
jquery: ['jquery'],
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dll'),
library: '[name]_[hash]', // 打包的库里面向外暴露出的内容叫什么名字
},
plugins: [
// 打包生成一个 manifest.json --> 提供和 jquery 映射
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射库的暴露的内容名称
path: resolve(__dirname, 'dll/manifest.json'), // 输出文件路径
}),
],
mode: 'production',
};
4.运行指令
bash
npx webpack