Open kangyana opened 1 year ago
如果最终打包生成的 main.js 既没有做 code spliting,也没有做 hash 化路径。 大可以通过在 index.html 中手动控制 JS 资源。
main.js
hash
index.html
<body> <script src="main.js" defer /> </body>
但往往事与愿违:
main.8a9b3c.js
verdor.js
publicPath
因此需要有一个插件自动做这种事情。在 webpack 的世界里,它是 html-webpak-plugin (opens new window), 在 rollup 的世界里,它是 @rollup/plugin-html (opens new window)。
以 html-webpack-plugin 为例,它在 compilation 处理资源的 processAssets 获得其打包生成的资源。 最小实现如下,可在 mini-node:html-webpack-plugin (opens new window)获得源码并运行示例。
html-webpack-plugin
compilation
processAssets
class HtmlWebpackPlugin { constructor(options) { this.options = options || {}; } apply(compiler) { const webpack = compiler.webpack; compiler.hooks.thisCompilation.tap("HtmlWebpackPlugin", (compilation) => { // compilation 是 webpack 中最重要的对象,文档见 [compilation-object](https://webpack.js.org/api/compilation-object/#compilation-object-methods) compilation.hooks.processAssets.tapAsync( { name: "HtmlWebpackPlugin", // processAssets 处理资源的时机,此阶段为资源已优化后,更多阶段见文档 // https://webpack.js.org/api/compilation-hooks/#list-of-asset-processing-stages stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE, }, (compilationAssets, callback) => { // compilationAssets 将得到所有生成的资源,如各个 chunk.js、各个 image、css // 获取 webpac.output.publicPath 选项,(PS: publicPath 选项有可能是通过函数设置) const publicPath = getPublicPath(compilation); // 本示例仅仅考虑单个 entryPoint 的情况 // compilation.entrypoints 可获取入口文件信息 const entryNames = Array.from(compilation.entrypoints.keys()); // entryPoint.getFiles() 将获取到该入口的所有资源,并能够保证加载顺序!!!如 runtime-chunk -> main-chunk const assets = entryNames .map((entryName) => compilation.entrypoints.get(entryName).getFiles() ) .flat(); const scripts = assets.map((src) => publicPath + src); const content = html({ title: this.options.title || "Demo", scripts, }); // emitAsset 用以生成资源文件,也是最重要的一步 compilation.emitAsset( "index.html", new webpack.sources.RawSource(content) ); callback(); } ); }); } }
如果最终打包生成的
main.js
既没有做 code spliting,也没有做hash
化路径。 大可以通过在index.html
中手动控制 JS 资源。但往往事与愿违:
main.js
即我们最终生成的文件带有hash
值,如main.8a9b3c.js
。verdor.js
,同样带有hash
。publicPath
,而在生产环境与测试环境的publicPath
并不一致。因此需要有一个插件自动做这种事情。在 webpack 的世界里,它是 html-webpak-plugin (opens new window), 在 rollup 的世界里,它是 @rollup/plugin-html (opens new window)。
而注入的原理为当打包器已生成 entryPoint 文件资源后,获得其文件名及
publicPath
,并将其注入到 html 中。以
html-webpack-plugin
为例,它在compilation
处理资源的processAssets
获得其打包生成的资源。 最小实现如下,可在 mini-node:html-webpack-plugin (opens new window)获得源码并运行示例。