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 config
Configuration
The config object supports the following options:
caddyImportFile
: filepath relative to your webpackoutput
directory which you will import into your Caddyfile (default:push.caddy
);allAnonymous
: Addcrossorigin=anonymous
directive to all pushed assets regardless of MIME type (default:false
)headerPath
: path beginning with '/' to which Caddy will add theLink
header (default:'/'
);includePatterns
: Array ofRegExp
or glob patterns for assets to be included in theLink
header asrel=preload
and pushed to the client (default:[/\.(html|css|js)(\?.*)?$/]
);ignorePatterns
: Array ofRegExp
or glob patterns for excluding assets (default:[]
)prefetchPatterns
: Array ofRegExp
or 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.html
The 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 -Link
Exluding 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...excludePattern
regex + globs