Skip to content

Instantly share code, notes, and snippets.

@prutya
Last active December 28, 2022 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prutya/740bee596eaccd6cfc4be807a760aaf3 to your computer and use it in GitHub Desktop.
Save prutya/740bee596eaccd6cfc4be807a760aaf3 to your computer and use it in GitHub Desktop.
A Webpack plugin to automatically generate Cloudflare Pages compatible _headers file to enable HTTP-2 Server Push
# Generated by ServerPushPlugin
/
Link: <index.js>; rel=preload; as=script
Link: <index.css>; rel=preload; as=stylesheet
const HtmlWebpackPlugin = require("html-webpack-plugin");
const FilePrefix = "# Generated by ServerPushPlugin";
class ServerPushPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.compilation.tap("ServerPushPlugin", (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(
"ServerPushPlugin",
(data, callback) => {
const assets = data.assets;
const source = this.generateAssetHeaders(assets);
console.info(
`Generated ${this.options.headersFile} file:\n${source}`
);
compilation.assets[`${this.options.headersFile}`] = {
source: () => source,
size: () => source.length,
};
callback(null, data);
}
);
});
}
generateAssetHeaders(assets) {
const scriptHeaders = assets.js.map(
(path) => ` Link: <${path}>; rel=preload; as=script`
);
const styleHeaders = assets.css.map(
(path) => ` Link: <${path}>; rel=preload; as=style`
);
return `${FilePrefix}\n\n/\n${scriptHeaders
.concat(styleHeaders)
.join("\n")}\n`;
}
}
module.exports = ServerPushPlugin;
module.exports = {
plugins: [
new HtmlWebpackPlugin({ template: "./src/index.html" }),
new ServerPushPlugin({ headersFile: "_headers" }),
// ...
],
// ...
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment