html-webpack-plugin 4 已发布!
当“mode”为production时,默认启用代码压缩 #1048
feat(template): 支持自定义模板参数 #830
Webpack 5 支持计划? #1269
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
虽然耗时太久,但新的主要版本终于html-webpack-plugin从测试版跃升为稳定版!
表现!
本次版本发布的一个重要目标是提高开发和生产构建过程中的性能。
性能提升主要得益于compilation.getStats().toJson()webpack 核心团队(由@sokra开发)提供的新 API,该 API 无需再使用旧版本。这个新 API 提供了将脚本和样式注入 HTML 代码所需的所有信息。
但遗憾的是,依赖该 API 意味着webpack 1-3 版本将不再受支持。
为了进一步提高性能,我们从头开始重建了整个缓存方法,以减少编译工作量。
内测用户的反馈非常好!
#953 “五次最佳构建的总时间从 10.41 秒(使用 4.0.0-alpha 版本)缩短到 10.29 秒——现在只比完全不使用插件时慢了 130 毫秒:-)”
#962:“作为参考,我的项目(自 #962 以来已大幅增长)在不进行这些更改的情况下构建时间约为 8000 毫秒,而进行这些更改后构建时间约为 1000 毫秒。”
在进行这些性能改进的过程中,我编写了一个cpuprofile-webpack-plugin——一个用于分析 webpack 构建性能的小工具,不仅用于生产构建,更重要的是用于开发过程中的重新编译。
欢迎尝试一下,然后告诉我你的想法 :)
模板语言支持
自 html-webpack-plugin 2.x 版本起,它就可以使用 webpack 配置文件中指定的加载器。因此,它不仅能够编译.ejs模板,还能编译任何可以用 webpack 加载器转译的代码(例如hbs,ejs` webpack - loader` 、...twigdustpughtljs, ts, jsxtsx
使用 JavaScript 或 JSX 模板甚至可以生成应用程序的静态服务器端渲染版本。
html-webpack-plugin 模板:
import ReactDOMServer from 'react-dom/server';
import React from 'react';
import { App } from './App';
export default () => `
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Server Side Rendering Demo</title>
</head>
<body>
<div id="root">${ReactDOMServer.renderToString(<App />)}</div>
</body>
</html>
`
有关如何将加载器连接到 html-webpack-plugin 的更多详细信息,请查看模板选项文档或查看html-webpack-plugin jsx codesandbox。
使用 html-webpack-plugin 在应用程序中预渲染静态页面的另一种方法是使用来自@developit的prerender-loader。
元标签
html-webpack-plugin 现在无需编写自定义模板即可注入 meta 标签:
new HtmlWebpackPlugin({
meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'},
})
基本标签
与元标签类似,现在也可以添加基本标签:
new HtmlWebpackPlugin({
base: '/',
})
零配置自定义模板
现在无需配置即可自定义模板。
从版本 4 开始,html-webpack-plugin 会查找本地src/index.ejs文件。如果找到此类文件,则会将其用作模板:
默认压缩
感谢@edmorley的工作,我们得以在 webpack 以特定模式运行时默认启用 HTML 压缩。可以通过在 html-webpack-plugin 配置中production添加相应内容来禁用此行为。minification: false
当“mode”为production时,默认启用代码压缩 #1048
之前默认情况下文件压缩功能是关闭的。现在,如果minify满足undefined特定mode条件'production',则可以使用以下选项启用文件压缩:
{
collapseWhitespace : true ,
removeComments : true ,
removeRedundantAttributes : true ,
removeScriptTypeAttributes : true ,
removeStyleLinkTypeAttributes : true ,
useShortDoctype : true
}
这些选项基于 create-react-app、Neutrino 和 vue-cli 的设置,希望能够做到相对保守。参见:https://github.com/jantimon/html-webpack-plugin/issues/1036#issuecomment-421408841 和 https://github.com/kangax/html-minifier#options-quick-reference
mode无论设置如何,都可以启用这些默认设置,只需将 `--minification-inference` 设置minify为true`--minification-inference` 即可(之前这样做会将一个空对象传递给 html-minifier,这意味着大多数压缩功能都被禁用)。同样,即使在生产环境中,也可以通过将 `--minification-inference` 设置为 `--minification-inference` 来禁用minify压缩false。
此更改对将对象传递给 . 的用户没有影响minify。
修复了 #1036。
允许修改模板变量
Evan,你要求提供更好的方法来修改发送到模板的值:
feat(template): 支持自定义模板参数 #830
这样,用户就可以注入自定义变量,以便在模板插值中使用,例如简化webpackConfig.output.publicPath为更短的形式。
文档/测试用例不包含在内,但如果这听起来是个好主意,我可以根据要求添加。
最终结果是新增了一个templateVariables选项,允许向process.env发送到模板的值中添加额外数据:
非阻塞脚本加载
以往所有脚本标签都添加到 body 标签的末尾。
但现在所有现代浏览器都允许并行加载 JavaScript,而不会暂停 HTML 解析,因此此scriptLoading选项可以加快用户页面的加载速度。
用法:
new HtmlWebpackPlugin({
scriptLoading: 'defer'
})
新钩子
webpack 核心团队要求升级到新的 hook 系统,以进一步提高 webpack 构建速度。
这些钩子允许插件开发者更改 html-webpack-plugin 的默认行为。下图展示了流程和钩子(beforeAssetTagGeneration,,,,,):alterAssetTagsalterAssetTagGroupsafterTemplateExecutionbeforeEmitafterEmit
以下是一个插件示例,该插件会在钩子函数中操作生成的 html 文件beforeEmit:
const HtmlWebpackPlugin = require('html-webpack-plugin');
class MyPlugin {
apply (compiler) {
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
// Static Plugin interface |compilation |HOOK NAME | register listener
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
'MyPlugin', // <-- Set a meaningful name here for stacktraces
(data, cb) => {
// Manipulate the content
data.html += 'The Magic Footer'
// Tell webpack to move on
cb(null, data)
}
)
})
}
}
module.exports = MyPlugin
更多信息请查看自述文件中的事件部分。
贡献者
世界各地的人都联系我寻求帮助,提出建议并参与新功能的开发,纠正拼写错误,甚至解决整个问题。非常感谢,请继续保持!:)
如果您对本次发布有任何反馈,请创建问题或在推特上联系我@jantimon(私信已开启)。
赞助商
非常感谢过去几年来支持我们发展的所有赞助商,
特别是TipeIO和Principal Financial Services, Inc.。
完整更新日志
接下来会发生什么?
下一个目标是完全兼容 Webpack 5,特别是新的 Webpack 5 FileSystemInfoAPI,以解决……
。
另一个目标是进一步缩短浏览器加载时间。对于支持预加载的浏览器,@sokra提出了一种比之前更快的方案scriptLoading: 'defer'。







