caddy-push-webpack-plugin v0.3.1
caddy-push-webpack-plugin
Generate a Caddy server header directive with Link preloads for for effortless leveraging of Caddy's link header detection for http2 server push.
WARNING: There could very well be serious security issues in deploying this technique that I am not clever enough to recognize. Use at your own risk!
NOTE: You must import the generatated file in your Caddyfile using Caddy's import directive, and then restart your Caddy instance in order for the changes to take effect.
Usage
Require the plugin...
const caddyPushPlugin = require('caddy-push-webpack-plugin');Include the plugin in your webpack config...
// ...webpack config
plugins: [
new caddyPushPlugin(),
],
// ...more webpack configConfiguration
The config object supports the following options:
caddyImportFile: filepath relative to your webpackoutputdirectory which you will import into your Caddyfile (default:push.caddy);allAnonymous: Addcrossorigin=anonymousdirective to all pushed assets regardless of MIME type (default:false)headerPath: path beginning with '/' to which Caddy will add theLinkheader (default:'/');includePatterns: Array ofRegExpor glob patterns for assets to be included in theLinkheader asrel=preloadand pushed to the client (default:[/\.(html|css|js)(\?.*)?$/]);ignorePatterns: Array ofRegExpor glob patterns for excluding assets (default:[])prefetchPatterns: Array ofRegExpor glob patterns which will receive a prefetch directive instead of preload (default:[])includeFiles: Array (default:[]) of objects for manually defining custom Link preload entries. Each included object supports the following properties:{ path: `/path/to/your/asset.json`, // required, no default as: `fetch`, // required, no default crossorigin: `anonymous`, // optional CORS attribute, no default type: `application/json`, // option type attribute, no default nopush: false, // boolean; optional directive instructing clients to preload, but prevent server push; default false }See the MDN documentation for a list of acceptable 'as' attribute values
Example
Assuming webpack produces the following assets:
- static/js/app.js
- static/css/style.css
- static/font/superCoolFont.woff
- favicon.ico
- index.htmlThe following plugin config:
new caddyPushPlugin({
caddyImportFile: `foo-directive.caddy`,
headerPath: `/login`,
includePatterns: /\.(css|js|ico)$/,
includeFiles: [
{
path: `/static/font/superCoolFont.woff`,
as: `font`,
crossorigin: `anonymous`,
nopush: true,
}
],
}),...will add an additional file to your assets:
- static/js/app.js
- static/css/style.css
- static/img/dancing-waffle.gif
- favicon.ico
- index.html
- foo-directive.caddy # <-- this...which will look like so:
header /login {
Link "</static/js/app.js>; rel=preload; as=script, </static/js/app.js>; rel=preload; as=script, </static/css/style.css>; rel=preload; as=style, </favicon.ico>; rel=preload; as=icon, <//some-cdn.example/superCoolFont.css>; rel=preload; as=style; crossorigin=anonymous; nopush;"
}
# Auto-generated for security reasons
status 404 /foo-directive.caddy...which you then import in your Caddyfile:
super-cool-app.example {
# ... Caddyfile config stuff
# don't forget the push directive!
push
import "/absolute/path/to/app/foo-directive.caddy"
# ... rest of your Caddyfile
}Caveats
Cache awareness
If you use the default headerPath ( / ), Caddy is going to push every asset in your generated Link header for every resource request to your site domain. You probably do not want this, and must disable this behavior on a per-asset and/or per-directory basis like so:
header /static -Link
header /login/_session -Link
header /other/example/path/lol.jpg -LinkExluding assets
If you would like to exclude a particular asset for whatever reason, add a negative lookahead regular expression construct to the includePatterns array e.g. /^(?!dont-push-me\.js)/
Server restart
After uploading your generated files to your server, you'll need to restart your Caddy instance in order for any changes to take effect.
Todos
- Confer with Caddy devs about possible security issues
- Learn to write tests, and write tests!
- Add support asset file globbing
Add support forUse use a negative lookahead...excludePatternregex + globs