Bundle Code for CloudFront Functions (V2.0) with ESBuild
My esbuild configuration to package code for CloudFront Functions.
CloudFront Functions provide an way to rewrite HTTP requests that are handled by AWS CloudFront distributions.
They are somewhat opinionated about what kind of code they like to run. Getting your average TypeScript source file into an acceptable shape for them to run is not an easy endeavour.
In this article, I share an easy way to package your functions to CloudFront Functions.
The key is to use this esbuild configuration (I am indebted to this GitHub comment to finally cobble something together that worked):
const esbuildConfig = {
outfile: 'function.js',
entryPoints: ['your-source-file.ts'],
minify: false,
minifyIdentifiers: false,
format: 'cjs',
banner: {
js: 'var module = {}; var exports = {};',
},
treeShaking: false,
bundle: true,
target: 'es5',
logLevel: 'info',
supported: {
'const-and-let': true,
'exponent-operator': true,
'template-literal': true,
arrow: true,
'rest-argument': true,
'regexp-named-capture-groups': true,
'async-await': true,
'unicode-escapes': true,
},
};
Key explanations:
format: 'cjs': Technically CF functions support esm but we want to keep everything as low tech as possible.banner: Provides globalmoduleandexportsobjects to prevent the runtime from crashing upon encountering these variable names.target: 'es5': Note, esbuild does not actually support making 'es5' code - this more or less discourages it from messing up our original code too much.supported: Enables specific modern features supported in CloudFront functions V2.bundle: true: Includes all dependencies in a single fileminify: false: We want esbuild to do as little as possible to mess up our code. You can try switching it on, chances are it will still work.
Background
AWS CloudFront long supported rewriting requests using Lambda@Edge. This is what I have been doing for all Goldstack templates and my applications built on top of them.
However, with the introduction of the new pricing plans for AWS CloudFront I felt obliged to review my CloudFront configurations.
I especially love that the CloudFront flat-rate plans cancel out the pesky USD0.50 per month Route 53 charge for domains.
Turns out, the free flat-rate plan does not support Lambda@Edge. Instead, I would need to use CloudFront Functions.
I was actually quite happy with that, since Lambda@Edge functions have been giving me big headaches in end-to-end testing (they take FOREVER to delete).
In any case, after having figured out the bundling, I still have some way to go until this is all ready, but when it is, I will release updated version of the following templates:
- Next.js + Tailwind
- Next.js + Bootstrap
- Next.js
- and probably a few others as well
If you are interested in the full source code, you can find it in this PR: [Next.js templates]: Updating CloudFront configuration so that it becomes eligible for AWS free tier (opposed to pay as you go)