前端前端构建构建工具【免费下载链接】html-webpack-pluginSimplifies creation of HTML files to serve your webpack bundles项目地址https://gitcode.com/gh_mirrors/ht/html-webpack-plugin点击查看免费下载本篇技术指南基于 html-webpack-plugin 仓库中 examples/README.md 的示例索引展开逐一对仓库内置的 13 个示例涵盖 chunk 优化、自定义模板、资源注入位置、多页面、模板参数覆盖等场景进行源码级拆解。读者读完本文后将掌握 html-webpack-plugin 从零配置使用到模板引擎深度定制、从单页面到多页面构建的完整实战能力并理解其标签生成tag object与模板参数template parameters的底层机制。一、示例总览一张索引表看懂插件能力矩阵examples/README.md以一张表格汇总了仓库内置的示例集合这些示例全部位于 examples 目录下每个子目录都自带可独立运行的webpack.config.js与配套模板/入口文件示例目录核心演示点Appcacheappcache生成 HTML5 AppCache 清单相关页面Chunk Optimizationchunk-optimization多入口 splitChunks公共代码提取Custom Templatecustom-template自定义 underscore 模板 内联 partialCustom Script / Link tag positioncustom-insertion-position通过inject: false自由控制注入位置Defaultdefault零配置开箱即用Faviconfaviconfavicon选项自动注入站点图标Html Loaderhtml-loader复用模板生成多个 HTML 页面Inlineinline使用 pug 模板引擎 关闭自动注入Javascript-advancedjavascript-advancedJS 模板函数可异步、可读取参数Javascriptjavascript用 JavaScript 动态生成模板Pug Loaderpug-loaderpug-loader 编译模板与 include 语法Sort Manuallysort-manually手动控制 chunk 注入顺序Template Parameterstemplate-parameters覆盖内置模板参数从仓库实际目录结构看multi-page 目录同样存在并提供了多页面生成示例但未出现在上述索引表中本文一并收录讲解。这些示例覆盖了 html-webpack-plugin 日常使用中的全部核心配置维度入口选择chunks、注入控制inject、模板引擎template、输出命名filename与参数传递templateParameters是学习该插件最直接的一手资料。二、零配置入门new HtmlWebpackPlugin()就够了examples/default/webpack.config.js 展示了插件的默认行为——除了引入插件外不需要任何额外配置var path require(path); var HtmlWebpackPlugin require(../..); module.exports { context: __dirname, entry: ./example.js, output: { path: path.join(__dirname, dist/webpack- webpackMajorVersion), publicPath: , filename: bundle.js, }, module: { rules: [ { test: /\.css$/, use: [style-loader, css-loader] }, { test: /\.png$/, type: asset/resource }, ], }, plugins: [new HtmlWebpackPlugin()], };该示例的 readme.md 将其定位为 zero-config example——只使用默认配置。new HtmlWebpackPlugin()会自动完成三件事自动生成index.html默认输出到 webpack 的output.path目录自动注入所有编译产物默认inject: true将 entry 产出的script标签插入body底部将 CSS 产物以link形式插入head使用内置默认模板插件自带的 default_index.ejs 模板无需任何自定义模板文件。注意示例中webpackMajorVersion的写法——通过读取webpack/package.json的版本号将输出目录命名为dist/webpack-4、dist/webpack-5等这使得同一份示例代码可以跨 webpack 大版本运行是官方示例通用的兼容性处理手法。chunk-optimization 的 readme 同样标注为 zero-config example但它的配置实际演示了更复杂的 chunk 优化场景见下文第六节。三、自定义 HTML 模板从 EJS 到 JS 模板函数3.1 基于 EJS 的自定义模板与 partial 内联custom-template 演示了自定义 underscore/EJS 模板的写法。webpack.config.js 中通过template: template.html指定模板文件而模板内部用require配合html-loader内联一个公共 partial!-- examples/custom-template/template.html -- !doctype html html langen head meta charsetutf-8 / title% htmlWebpackPlugin.options.title %/title meta nameviewport contentwidthdevice-width, initial-scale1 / /head body % require(html-loader!./partial.html).default % /body /html核心技巧是% require(html-loader!./partial.html).default %这一行见 readme.md模板在编译时被当作 webpack 模块处理require(html-loader!...)会触发 html-loader 解析目标 HTML 文件并返回其默认导出.default取出编译后的字符串。配合 partial.html 中的h2Partial/h2与img srclogo.png /实现了模板片段复用。模板内还可以访问htmlWebpackPlugin.options其中保存了插件实例的所有配置选项title、favicon、meta等这是自定义模板中读取插件配置的标准入口。3.2 用 JavaScript 动态生成模板当模板逻辑过于复杂、或需要程序化生成 HTML 时可以直接把template指向一个 JS 文件。javascript 示例的 template.js 展示了最简形式——模块导出一个字符串// examples/javascript/template.js var partial require(./partial.html).default; var universal require(./universal.js); // Export a function / promise / or a string: module.exports universal() new Date().toISOString() partial;导出值可以是字符串、函数或 Promise 三种形态。这里导出的字符串由universal.js的输出、当前时间戳和 html-loader 编译后的 partial 拼接而成生成结果会随构建时间变化。该示例的 readme.md 特别提示调试 JS 模板编译结果的最佳方式是设置devtool: eval见 webpack.config.js 与 javascript-advanced/webpack.config.js这样可以在浏览器 devtools 中直接查看模板函数的执行与报错堆栈。universal.js 则演示了同构isomorphic用法——同一个模块在前后端都能运行// This file is used for frontend and backend use strict; // If compiled by the html-webpack-plugin // HTML_WEBPACK_PLUGIN is set to true: var backend typeof HTML_WEBPACK_PLUGIN ! undefined; module.exports function () { return Hello World from (backend ? backend : frontend); };插件在编译模板时会注入全局变量HTML_WEBPACK_PLUGIN因此模块可以通过typeof HTML_WEBPACK_PLUGIN ! undefined判断自己正运行在插件编译环境后端/构建期还是被打包进浏览器前端实现一套代码两端复用。3.3 函数式模板接收参数、支持异步javascript-advanced 与 javascript 示例的区别在于其 template.js 导出的是一个接收templateParams的函数module.exports function (templateParams) { var html htmlhead title templateParams.htmlWebpackPlugin.options.title /title /headbody universal() - partial /body/html; return html; };如 readme 所述it allows takes parameters from the config and works asynchronously函数签名接收插件传入的模板参数对象templateParams从而可以读取配置项如templateParams.htmlWebpackPlugin.options.title。函数必须返回字符串或 Promise 字符串因此模板中也可以执行异步操作这是动态模板的高级形态。四、模板参数覆盖templateParameters的两种用法template-parameters 演示如何覆盖插件内置的模板参数。其 webpack.config.js 提供了两种方式new HtmlWebpackPlugin({ // 方式一传入普通对象会与默认参数做浅合并v4 起支持 templateParameters: { foo: bar, }, // 方式二传入函数全权控制返回给模板的参数对象 // templateParameters: (compilation, assets, assetTags, options) { // return { // compilation, // webpackConfig: compilation.options, // htmlWebpackPlugin: { // tags: assetTags, // files: assets, // options // }, // foo: bar // }; // }, template: index.ejs, });两种方式对应不同的控制粒度代码注释中标注 New in version 4对象合并传入的键值会与默认模板参数合并适合只追加少量自定义变量的场景函数全权控制函数接收(compilation, assets, assetTags, options)四个参数——compilation是 webpack 编译对象、assets是资源文件信息、assetTags是插件生成的标签分组、options是插件配置——返回值将作为模板可用的全部变量同时保留内置的htmlWebpackPlugin结构tags、files、options。模板端index.ejs直接消费自定义参数!DOCTYPE html html head meta charsetutf-8 title% foo %/title /head body /body /html即% foo %渲染出配置中的bar。这是向模板注入业务数据的标准通道readme 原文This example shows how you can overwrite the built in template parameters。五、控制资源注入位置与站点图标5.1inject: falseheadTags/bodyTags自由排版默认情况下插件将脚本统一注入body底部。当需要精确控制注入位置时可以关闭自动注入并在模板中手工放置标签。custom-insertion-position 正是为此设计。其 webpack.config.js 设置了inject: false并附带meta与minify: false选项注释标明 only used for demo purposesnew HtmlWebpackPlugin({ template: index.ejs, inject: false, meta: { charset: { charset: utf-8 }, viewport: widthdevice-width, initial-scale1, }, minify: false, }),模板 index.ejs 中使用两个内置模板参数完成手工注入!DOCTYPE html html head % htmlWebpackPlugin.tags.headTags % titleCustom insertion example/title /head body All scripts are placed here: % htmlWebpackPlugin.tags.bodyTags % scriptconsole.log(Executed after all other scripts)/script /body /html如 readme.md 所说明headTags与bodyTags是数组因此可以直接使用Array.prototype上的任意方法如filter对标签进行筛选、排序后渲染% htmlWebpackPlugin .tags .headTags .filter((tag) tag.tagName meta) .join() %这个用法意味着你可以在模板中对注入标签做任意变换——例如只注入 meta 标签、按条件丢弃某些 script、甚至重排顺序。readme 还指引读者深入源码理解标签对象结构createHtmlTagObject位于 lib/html-tags.js与prepareAssetTagGroupForRendering位于 index.js。5.2 标签对象的底层结构从源码看lib/html-tags.js 中的createHtmlTagObject构造出统一结构的标签对象function createHtmlTagObject(tagName, attributes, innerHTML, meta) { return { tagName: tagName, voidTag: voidTags.indexOf(tagName) ! -1, attributes: attributes || {}, meta: meta || {}, innerHTML: innerHTML, }; }每个标签对象包含五个字段tagName标签名、voidTag是否为自闭合标签如meta、attributes属性映射、meta插件元信息如来源插件名、innerHTML内联内容。这正是模板中tag.tagName meta这类过滤条件能够成立的原因。同文件还定义了HtmlTagArraylib/html-tags.js——一个重写了toString()的数组子类toString()会执行this.join()把标签数组直接拼成 HTML 字符串。因此模板里对headTags/bodyTags调用.join()或直接插值因为 EJS 的% %会调用toString()即可输出完整标签。5.3 favicon 站点图标注入favicon 示例的 webpack.config.js 展示了favicon选项的用法new HtmlWebpackPlugin({ title: HtmlWebpackPlugin example, favicon: favicon.ico, filename: favicon.html, }),插件会将该路径的favicon.ico作为 webpack 资源处理复制到输出目录并自动在生成的 HTMLhead中注入link relicon hreffavicon.ico。六、多入口、chunk 拆分与多页面构建6.1 多页面一份配置生成多个 HTMLmulti-page 演示了最优雅的多页面方案——多个 entry 配一个插件实例filename支持[name]占位符自动映射entry: { first: ./first.js, second: ./second.js }, output: { filename: [name].js }, plugins: [ new HtmlWebpackPlugin({ filename: [name].html }), ],由于 chunk 与 filename 一一对应最终会生成first.html注入first.js与second.html注入second.js两个页面。而 chunk-optimization 则展示了另一种多页面做法——多个插件实例分别指定chunksnew HtmlWebpackPlugin({ filename: entryA.html, chunks: [entryA] }), new HtmlWebpackPlugin({ filename: entryB.html, chunks: [entryB] }), new HtmlWebpackPlugin({ filename: entryC.html }), // 未指定 chunks注入全部6.2 chunk 优化splitChunks 与页面级资源裁剪chunk-optimization 的配置虽标注为 zero-config实际演示的是 webpacksplitChunks与插件chunks选项的配合optimization: { splitChunks: { chunks: all, minSize: 0, cacheGroups: { libMath: { test: /lib-(multiply|sum)/, name: libMath, chunks: all }, libText: { test: /lib-concat/, name: libText, chunks: all }, }, }, },两个 entryentryA.js、entryB.js共享的lib-*模块会被提取为libMath、libText两个公共 chunklib-sum.js、lib-multiply.js 归入libMathlib-concat.js 归入libText。随后entryA.html仅注入entryA及其依赖的公共 chunkentryB.html仅注入entryB及其依赖的公共 chunkentryC.html未配置chunks注入全部产物。通过chunks选项插件可以将页面脚本裁剪到最小集避免每个页面加载无关代码——这是多页面应用中控制资源加载的核心手段。6.3 手动排序chunksSortMode: manualsort-manually 用于解决脚本注入顺序问题。其 webpack.config.js 定义了 5 个入口ae并通过chunksSortMode: manual让chunks数组的书写顺序即注入顺序new HtmlWebpackPlugin({ inject: true, filename: first-file.html, template: template.html, chunksSortMode: manual, chunks: [a, b, c], }), new HtmlWebpackPlugin({ inject: true, filename: second-file.html, template: template.html, chunksSortMode: manual, chunks: [a, b, d], }),两个页面共享a.js、b.js分别追加c.js与d.js注入顺序严格遵循chunks数组字面量顺序适合对脚本执行顺序有强依赖的遗留项目。七、扩展模板引擎pug 与 html-loader 的实战组合7.1 pug-loader 与 include 语法pug-loader 演示了在插件中接入 pug 模板引擎。webpack 侧配置{ test: /\.pug$/, loader: pug-loader }插件侧template: template.pug即可。模板 template.pug 展示了 pug 的include与模板参数读取doctype html html head title htmlWebpackPlugin.options.title body #main - locals.time new Date(01 01, 1999); include ./time.pugtitle htmlWebpackPlugin.options.title读取配置中的title: pug demoinclude ./time.pug复用子模板 time.pugreadme 说明该示例为 isomorphic——time.pug 可同时被后端与前端加载。其 readme.md 明确指出这是使用不同模板引擎此处为 pug在前后端加载模板的示范。7.2 模板复用一份模板、多个页面html-loader 示例的核心价值在于模板复用两个插件实例指向同一个 template.html分别生成不同文件名的页面new HtmlWebpackPlugin({ filename: index.html, favicon: favicon.ico, template: template.html }), new HtmlWebpackPlugin({ filename: about.html, favicon: favicon.ico, template: template.html }),配合{ test: /\.html$/, loader: html-loader }规则模板中的img srclogo.png等资源引用会被 html-loader 解析为 webpack 模块并输出带哈希的文件实现多页面共享同一模板、各自输出独立页面。7.3 inline 示例pug 关闭注入inline 是 pug 模板的另一变体其 webpack.config.js 组合了inject: false、cache: false与favicon选项new HtmlWebpackPlugin({ inject: false, cache: false, template: template.pug, filename: index.html, favicon: favicon.ico, title: pug demo, }),inject: false表示脚本不自动注入由模板自行排版cache: false关闭模板编译缓存保证每次构建都重新编译模板readme.md 将该示例定位为 isomorphic pug 用法。八、运行与验证示例所有示例的入口文件如example.js与webpack.config.js均位于各自示例目录运行方式与普通 webpack 项目一致在示例目录下安装依赖后执行npx webpack示例通过webpackMajorVersion将产物输出到dist/webpack-大版本号目录便于对比不同 webpack 大版本下的行为然后打开输出的 HTML 验证注入结果。仓库的 spec/example.spec.js 测试即针对这些示例编写可参考其断言来确认各配置的预期产物例如验证生成的 HTML 中是否包含对应 script/link 标签。结语examples/README.md虽然只是一份简短的示例索引但其背后是 html-webpack-plugin 最完整的能力图谱从new HtmlWebpackPlugin()零配置起步到 EJS/JS/pug 多模板引擎、headTags/bodyTags手工注入、templateParameters参数覆盖、chunks/chunksSortMode资源编排再到多页面与 chunk 优化组合。结合 lib/html-tags.js 与 index.js 的源码读者可以清晰理解webpack 编译产物 → 标签对象 → 模板渲染的完整链路从而在实际项目中自由组合这些模式。赞分享前端前端构建构建工具【免费下载链接】html-webpack-pluginSimplifies creation of HTML files to serve your webpack bundles项目地址https://gitcode.com/gh_mirrors/ht/html-webpack-plugin点击查看免费下载相关推荐html-webpack-plugin 完全指南从零配置生成 HTML 到模板定制与 Hooks 扩展html webpack plugin 完全指南从零配置生成 HTML 到模板定制与 Hooks 扩展 html webpack plugin 是 webpa前端前端构建构建工具html-webpack-plugin 高级 JavaScript 模板函数式、异步与 isomorphic 渲染实战javascript-advanced 示例深度解析html webpack plugin 高级 JavaScript 模板函数式、异步与 isomorphic 渲染实战javascript advanced前端前端构建构建工具html-webpack-plugin 零配置多页应用示例一个插件实例批量生成多份 HTMLhtml webpack plugin 零配置多页应用示例一个插件实例批量生成多份 HTML 本篇技术指南以仓库 examples/multi page ht前端前端构建构建工具上一篇3 分钟上手 fanbox-dl快速备份你支持的 FANBOX 创作者内容下一篇TradSimpChinese三步把繁体中文电子书转成简体日文竖排也支持创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考