引言
在Web开发中,我们经常需要处理多个入口文件。这些入口文件是Webpack开始执行构建的起点。Webpack提供了对JavaScript的打包,但是JavaScript最终要挂在一个HTML文件下面,而处理这个index.html就是HtmlWebpackPlugin插件在做的事情。因此,对HtmlWebpackPlugin插件的深入理解和掌握,对于我们进行多入口文件打包,优化项目结构,提高开发效率都有着重要的意义。
HtmlWebpackPlugin插件简介HtmlWebpackPlugin插件介绍
HtmlWebpackPlugin是一个用于Webpack的插件,它可以简化创建服务于Webpack bundle的HTML文件。这在Webpack的输出包含了每次构建后hash值变化的文件名时尤其有用。HtmlWebpackPlugin会自动将引用插入到HTML中。
如何使用HtmlWebpackPlugin如何使用 HtmlWebpackPlugin
首先,我们需要在项目中安装HtmlWebpackPlugin。在你的项目根目录下运行以下命令:
npm install --save-dev html-webpack-plugin
然后,在你的webpack.config.js文件中,引入HtmlWebpackPlugin,并在plugins数组中使用它:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
filename: 'app.html',
template: 'src/app.html'
})
]
// ...
};
在这个例子中,HtmlWebpackPlugin会生成一个新的HTML文件,名为app.html。这个文件的内容是基于src/app.html文件,但是所有的JavaScript和CSS文件都会自动添加到新生成的HTML文件中。
HtmlWebpackPlugin的参数详解
HtmlWebpackPlugin插件的options参数讲得非常清晰,使用沉浸式翻译就可以中英文互译。你可以在这里查看更多关于options参数的信息。
template参数模板参数
Webpack模板的相对或绝对路径。默认情况下,它将使用src/index.ejs(如果存在)。请参阅文档了解详细信息。
模板默认提供一些变量
默认情况下,模板中提供以下变量(您可以使用templateParameters选项扩展它们):
- htmlWebpackPlugin: 特定于此插件的数据
- htmlWebpackPlugin.options: 传递给插件的选项哈希。除了此插件实际使用的选项之外,您还可以使用此哈希将任意数据传递到您的模板。
- htmlWebpackPlugin.tags: 准备好的headTags和bodyTags数组来渲染<base>、<meta>、<script>标签。可以直接在模板和文字中使用。例如:
<html>
<head>
<%= htmlWebpackPlugin.tags.headTags %>
</head>
<body>
<%= htmlWebpackPlugin.tags.bodyTags %>
</body>
</html>
- htmlWebpackPlugin.files: 直接访问编译过程中使用的文件。
- webpackConfig: 用于此编译的webpack配置。例如,这可以用来获取publicPath(webpackConfig.output.publicPath)。
- compilation: webpack编译对象。例如,这可用于获取已处理资源的内容并通过compilation.assets[...].source()将它们直接内联到页面中(请参阅内联模板示例)。
使用templateParameters参数来控制模板变量
这里给了一个Demo演示。注释里写得非常好,大概意思是在版本4时,才出现templateParameters这个参数,且这个参数可以是对象也可以是函数,如果是对象的话,则会跟默认参数进行合并,如果是函数的话,则会完全控制,完全控制的几个必备参数必须带上,否则就不能提供上面那几个默认参数的值了。
var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
context: __dirname,
entry: './example.js',
output: {
path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
publicPath: '',
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
// If you pass a plain object, it will be merged with the default values
// (New in version 4)
templateParameters: {
'foo': 'bar'
},
// Or if you want full control, pass a function
// templateParameters: (compilation, assets, assetTags, options) => {
// return {
// compilation,
// webpackConfig: compilation.options,
// htmlWebpackPlugin: {
// tags: assetTags,
// files: assets,
// options
// },
// 'foo': 'bar'
// };
// },
template: 'index.ejs'
})
]
};
index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- 这里比较关键的是上面返回一个对象有一个 foo key 这里是像 php 模板一样直接可以使用的 而并不属于某一个对象-->
<title><%= foo %></title>
</head>
<body>
</body>
</html>
在Electron-vue中的HtmlWebpackPlugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../src/index.ejs'),
templateParameters(compilation, assets, options) {
return {
compilation: compilation,
webpack: compilation.getStats().toJson(),
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options: options,
},
process,
}
},
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
},
') %>')
</script>
<% } %>
</head>
<body>
<div id="app"></div>
<!-- Set `__static` path to static files in production -->
<% if (!process.browser) { %>
<script>
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\\\/g, '\\\\\\\\')
</script>
<% } %>
<!-- webpack builds are automatically injected -->
</body>
</html>
打包后的index.html
保留了if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\\\/g, '\\\\\\\\')
这段代码,这段代码应该是yarn run dev
时能识别。
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>WADesk</title></head>
<body>
<div id=app></div>
<script>if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\\\/g, '\\\\\\\\')</script>
<script type=text/javascript src=renderer.js></script>
</body>
</html>
实战:使用HtmlWebpackPlugin进行多入口文件打包
在这个部分,我们将通过一个实际的例子来演示如何使用HtmlWebpackPlugin进行多入口文件打包。假设我们有一个项目,其中有两个入口文件:index.js和about.js。我们希望Webpack能够为这两个文件生成两个HTML文件:index.html和about.html。
首先,我们需要在webpack.config.js文件中定义两个入口点:
module.exports = {
entry: {
index: './src/index.js',
about: './src/about.js'
},
// ...
};
然后,我们可以使用HtmlWebpackPlugin来为每个入口文件生成一个HTML文件:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
chunks: ['index']
}),
new HtmlWebpackPlugin({
filename: 'about.html',
template: 'src/about.html',
chunks: ['about']
})
]
// ...
};
在这个例子中,我们使用了HtmlWebpackPlugin的chunks选项来指定每个HTML文件应该包含哪些入口点。例如,index.html只包含index入口点,而about.html只包含about入口点。
当我们运行Webpack时,它将为每个入口文件生成一个HTML文件,并将相应的JavaScript文件自动添加到HTML文件中。
结论
HtmlWebpackPlugin是一个非常强大的插件,它可以帮助我们简化HTML文件的创建和管理。通过深入理解HtmlWebpackPlugin的工作原理和参数,我们可以更好地利用它来优化我们的项目结构和提高开发效率。