html-webpack-plugin
一、认识
HtmlWebpackPlugin
是一个非常流行的 Webpack
插件,用于简化在 Webpack
打包过程中生成 HTML
文件的过程。它可以自动将 Webpack
打包生成的 JavaScript
和 CSS
文件注入到 HTML
文件中,从而避免手动修改 HTML
模板。
HtmlWebpackPlugin
的核心功能是自动生成 HTML
文件并注入相关的资源文件(例如 JavaScript
、CSS
等),通常用于动态生成一个 HTML
文件并包含 Webpack
打包后的资源文件。
二、准备
- 安装
html-webpack-plugin
依赖
yarn add html-webpack-plugin -D
三、配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html' // 通过模板生成 HTML 文件
})
]
};
三、配置项
3.1 hash
HtmlWebpackPlugin.hash
添加文件的 hash
值到输出的文件名中(例如:bundle.[hash].js
)。
true
:启用文件名哈希,防止缓存问题。
3.2 data
3.3 inject
HtmlWebpackPlugin.inject
控制如何将 JavaScript
和 CSS
文件注入到 HTML
文件中。
-
true
(默认):默认情况下,inject: true
会把所有的<script>
标签(通常是JavaScript
文件)自动插入到HTML
文件的<body>
标签的结束前。这是常见的默认行为,因为将<script>
放在</body>
标签前面可以避免阻塞页面的渲染,优化页面加载速度。 -
head
:将JavaScript
文件注入到HTML
文件的<head>
部分。这通常用于那些需要在页面加载时优先执行的脚本(例如,一些需要在页面加载前执行的代码)。 -
body
: 将JavaScript
文件注入到HTML
文件的<body>
部分(默认行为)。这种方式通常用于不影响页面渲染的脚本。 -
false
:不自动注入任何文件,通常需要手动插入资源。允许开发者手动控制资源插入的位置。果将inject
设置为false
,HTMLWebpackPlugin
就不会自动注入JavaScript
和CSS
文件。此时,你需要手动在生成的HTML
文件中添加<script>
或<link>
标签,指向打包后的资源文件。
语法
new HtmlWebpackPlugin({
inject: 'body', // 将这些标签插入到 <body> 底部(推荐的做法,避免阻塞渲染)。
})
new HtmlWebpackPlugin({
inject: 'head', // 将 <script> 和 <link> 标签插入到 <head> 部分。
})
3.4 minify
HtmlWebpackPlugin.minify
用于压缩生成的 HTML
文件,可以设置为 true
或提供压缩选项。例如minify: { collapseWhitespace: true, removeComments: true }
:压缩 HTML
,去除空格和注释。
3.5 chunks
HtmlWebpackPlugin.chunks
指定要注入的 JavaScript
和 CSS
文件的名称,默认为 all
,即注入所有入口文件对应的资源。例如:chunks: ['app']
只注入 app
相关的资源。
3.6 template
HtmlWebpackPlugin.template
指定一个 HTML
文件作为模板,插件会基于该模板生成 HTML
文件。如果不设置 template
,插件会默认生成一个简单的 HTML
文件。
3.7 filename
HtmlWebpackPlugin.filename
指定输出的 HTML
文件的名称(默认为 index.html
)。
四、使用场景
4.1 多页面
一、webpack.config.js
配置 entry
与 htmlWebpackPlugin
const Path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: {
entry1: Path.resolve(__dirname, "src", "entry1.js"),
entry2: Path.resolve(__dirname, "src", "entry2.js"),
},
output: {
filename: "[name].js",
path: Path.resolve(__dirname, "build"),
},
optimization: {
splitChunks: {
chunks: "all", // 代码分割应用于哪些情况: initial 同步 / async 异步 / all = initial + all
minSize: 0, // 分割出去的代码块最小的尺寸多大,默认是 30k . 0 为不限制,只有符合分割的要求就会分割
minChunks: 2, // 如果一个模块被多少个入口引用了才会分割, 2 为有两个才会分割
name: false, // 打包后的名称,默认规则是 分割名称
automaticNameDelimiter: "~", // 分隔符
cacheGroups: {
// 缓存组: 用来抽取满足不同规则的 chunk
verdors: {
chunks: "all",
test: /node_modules/, // 如果这个模块 request 路径包含 node_modules
priority: -10,
},
common: {
chunks: "all",
minSize: 0,
minChunks: 2,
priority: -20,
},
},
},
},
plugins: [
new HtmlWebpackPlugin({
chunks: ["entry1"],
filename: "index1.html",
template: Path.resolve(__dirname, "index1.html"),
}),
new HtmlWebpackPlugin({
chunks: ["entry2"],
filename: "index2.html",
template: Path.resolve(__dirname, "index2.html"),
}),
]
};
4.2 动态引入 CDN 依赖
webpack.config.js
配置 htmlWebpackPlugin
const Path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const cdnConfig = [
"https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js",
"https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js",
];
module.exports = {
mode: "development",
entry: Path.resolve(process.cwd(), "./src/index.js"),
output: {
path: Path.resolve(process.cwd(), "./build"),
filename: "index.js",
},
devServer: {
port: 8090,
open: true,
},
module: {
rules: [],
},
plugins: [
new HtmlWebpackPlugin({
title: "学习 Webpack",
template: Path.resolve(process.cwd(), "./public/index.html"),
cdn: cdnConfig,
}),
],
};
2. 配置模板文件 public/index.html
在html中配置的CDN引入脚本一定要在body内的最底部
,因为:
- 如果放在 body 上面或 header 内,则加载会阻塞整个页面渲染。
- 如果放在 body 外,则会在业务代码被加载之后加载,模块中使用了该模块将会报错。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<% if(htmlWebpackPlugin.options.cdn){%>
<% for(const i in htmlWebpackPlugin.options.cdn){%>
<script src='<%= htmlWebpackPlugin.options.cdn[i] %>'></script>
<% } %>
<% } %>
</body>
</html>