CDK constructs for esbuild, an extremely fast JavaScript bundler
Getting started | Documentation | Versioning
esbuild is an extremely fast bundler and minifier for Typescript and JavaScript. This package makes esbuild available to deploy lambda functions, static websites or to publish build artefacts (assets) for further use.
AWS CDK supports esbuild with Lambda Functions. However the implementation cannot be used with any other Constructs and doesn't expose all of esbuild's build interface.
This package is running esbuild directly in Node.js and bypasses Docker which the AWS CDK implementation uses. The approach is quicker and easier to use for Node.js users, but incompatible with other languages.
Install cdk-esbuild
and required peer dependencies:
npm install @mrgrain/cdk-esbuild @aws-cdk/core @aws-cdk/aws-s3-assets
💡 See Lambda Function for a complete working example of a how to deploy a lambda function.
Install the the lambda package:
npm install @aws-cdk/aws-lambda
Use TypeScriptCode
as the code
of a lambda function:
import * as lambda from "@aws-cdk/aws-lambda";
import { TypeScriptCode } from "@mrgrain/cdk-esbuild";
const bundledCode = new TypeScriptCode("src/index.ts");
const fn = new lambda.Function(this, "MyFunction", {
runtime: lambda.Runtime.NODEJS_14_X,
handler: "index.handler",
code: bundledCode,
});
💡 See Static Website with React for a complete working example of a how to deploy a React app to S3.
Install the S3 deployment package:
npm install @aws-cdk/aws-s3-deployment
Use TypeScriptSource
as one of the sources
of a static website deployment:
import * as s3 from "@aws-cdk/aws-s3";
import * as s3deploy from "@aws-cdk/aws-s3-deployment";
import { TypeScriptSource } from "@mrgrain/cdk-esbuild";
const websiteBundle = new TypeScriptSource("src/index.tsx");
const websiteBucket = new s3.Bucket(this, "WebsiteBucket", {
autoDeleteObjects: true,
publicReadAccess: true,
removalPolicy: RemovalPolicy.DESTROY,
websiteIndexDocument: "index.html",
});
new s3deploy.BucketDeployment(this, "DeployWebsite", {
destinationBucket: websiteBucket,
sources: [websiteBundle],
});
The package exports various different constructs for use with existing CDK features. A major guiding design principal for this package is to extend, don't replace. Expect constructs that you can provide as props, not complete replacements.
For use in lambda functions, the following classes implement lambda.Code
(reference):
TypeScriptCode
&JavaScriptCode
InlineTypeScriptCode
&InlineJavaScriptCode
InlineTsxCode
&InlineJsxCode
For use with S3 bucket deployments, classes implementing s3deploy.ISource
(reference):
- 🧺
TypeScriptSource
&JavaScriptSource
Code and Source constructs seamlessly plugin to high-level CDK features. They share the same set of parameters, props and build options:
Underlying classes the power the other features. You normally won't have to use them, but they are there if you need them:
-
TypeScriptAsset
&JavaScriptAsset
implementss3.Asset
(reference)
creates an asset uploaded to S3 which can be referenced by other constructs -
EsbuildBundling
implementscore.BundlingOptions
(reference)
provides a esbuild bundling interface wherever needed
ℹ️ Although these classes are currently identical, please use the appropriate class as functionality might diverge in future releases.
Default build options:
bundle=true
platform=node
target=nodeX
withX
being the major node version running the code
entryPoints: string | string[] | Record<string, string>
A single or list of relative paths to the entry points of your code from the root of the project.
-
props.buildOptions?
as per esbuild (reference)
All build options are optional.
Same defaults and functionalities apply, with a few changes as noted below. Generally speaking usage of entry and output options are different, as these are inferred by CDK. -
❌
buildOptions.entryPoints
Not available. Option is exposed as parameter. -
buildOptions.outdir: string
The actual path for the output directory is defined by CDK. However setting this option allows to write files into a subdirectory.
For example{ outdir: 'js' }
will create an asset with a single directory calledjs
, which contains all built files. This approach can be useful for static website deployments, where JavaScript code should be placed into a subdirectory.
Cannot be used together withoutfile
. -
buildOptions.outfile: string
Relative path to a file inside the CDK asset output directory.
For example{ outfile: 'js/index.js' }
will create an asset with a single directory calledjs
, which contains a single fileindex.js
. This can be useful to rename the entry point.
Cannot be used with multipleentryPoints
or together withoutdir
. -
buildOptions.absWorkingDir: string
Absolute path to the esbuild working directory and defaults to the current working directory.
Docker-based builds also use this path to mount local files into the container. A largeabsWorkingDir
can slow down the Docker build.
If paths cannot be found, a good starting point is to look at the concatenation ofabsWorkingDir + entryPoint
. It must always be a valid absolute path pointing to the entry point. When needed, the probably easiest way to setabsWorkingDir
is to use a combination ofresolve
and__dirname
(see "A note for library authors" below).
⚠️ A note for library authorsWhen developing a library consumed by other packages, you'll most likely have to set
absWorkingDir
. The easiest way to do this, is to resolve based on the directory name of the file, and traverse the tree upwards to the root of your library package (that's wherepackage.json
andtsconfig.json
are):// file: project/src/index.ts const props = { buildOptions: { absWorkingDir: path.resolve(__dirname, ".."), // now: /user/project }, };This will dynamically resolve to the correct path, wherever the package is installed.
-
props.copyDir?: string
⚠️ Experimental - Likely to change once esbuild supports this natively
Relative path to a directory copied to the output before the build is run (i.e esbuild will overwrite existing files). -
props.bundlerPriority?: BundlerPriority (BundlerPriority.AttemptLocal)
Set the priority order of available bundlers. It can be useful to limit use to one of the bundlers. For Docker, theabsWorkingDir
path (or current working directory) will be mounted into the container as context. By default bundling with a locally installed binary is attempted first and Docker will only be used if the local bundling fails.
ℹ️ Although these classes are currently identical, please use the appropriate class as functionality might diverge in future releases.
Default build options:
bundle=true
platform=browser
💡 See Static Website with React for a complete working example of a how to deploy a React app to S3.
➡️ Code and Source constructs share the same set of parameters, props and build options. Please see above for details.
An implementation of lambda.InlineCode
(reference) using the esbuild Transform API.
Inline function code is limited to 4 KiB after transformation.
-
code: string
The inline code to be transformed. -
transformOptions: TransformOptions
Options from the esbuild Transform API.Default transform options:
•loader=ts|js|tsx|jsx
(one ofts,js,tsx,jsx
depending on the used class)
Bundles the entry points and creates a CDK asset which is uploaded to the bootstrapped CDK S3 bucket during deployment. The asset can be used by other constructs.
ℹ️ The high-level constructs for
TypeScriptSource
andTypeScriptCode
(and respective JavaScript classes) actually just use this asset.
Default build options:
bundle=true
scope: cdk.Construct
id: string
props: TypeScriptAssetProps|JavaScriptAssetProps
-
props.entryPoints: string | string[] | Record<string, string>
A single or list of relative paths to the entry points of your code from the root of the project. -
props.copyDir?: string
⚠️ Experimental - Likely to change once esbuild supports this natively
Relative path to a directory copied to the output before the build is run (i.e esbuild will overwrite existing files). -
props.bundlerPriority?: BundlerPriority (BundlerPriority.AttemptLocal)
Set the priority order of available bundlers. It can be useful to limit use to one of the bundlers. For Docker, theabsWorkingDir
path (or current working directory) will be mounted into the container as context. By default bundling with a locally installed binary is attempted first and Docker will only be used if the local bundling fails. -
props.buildOptions?
as per esbuild (reference)
All build options are optional.
➡️ SeeTypeScriptCode
for detailed explanation on options.
Low-level class that can be used where a BundlingOptions
are required. This class provides the local und Docker-based bundling but doesn't come with any kind of safeguards.
-
buildOptions?
All esbuild options are available, with adapted functionality as described above. -
props.priority?: BundlerPriority (BundlerPriority.AttemptLocal)
Priority order of available bundlers. DefaultBundlerPriority.AttemptLocal
is to attempt using a locally installed binary first, retrying with Docker in case of failure. Can be set to only use either the local or Docker bundler. -
props.copyDir?: string
Copy additional files to the output directory, before the build runs. -
props.esbuildVersion?: string
Docker build only. A npm compatible version constraint. If not provided will attempt to read from apackage-lock.json
orpackage.json
in theabsWorkingDir
. Otherwise uses the constraint provided by this package (usually^0.x.0
).
Because esbuild is still in major version zero, this package must be considered unstable. Notably updates to the minimal version requirement of esbuild will be introduced in minor versions of this package and thus will contain any breaking changes esbuild introduces.
The package tracks the minor version number of CDK releases. It might work with newer versions of CDK, but has not been tested. Features changes, including breaking changes, will only be introduced alongside minor releases.
Patches releases will contain fixes to this library only and do not necessarily reflect CDK patches.
With the monolithic version 2 of CDK (aka Mono-CDK) approaching fast, versioning for this library will change as well.
A major 2.0 release will be marked alongside CDK. From that point on, this package will mostly use semantic versioning and not longer align version numbers with AWS CDK.
The big exceptions will be updates to the minimal version requirement of esbuild. As long as esbuild is still in major version zero, these requirement updates will be introduced as minor version updates.
Additionally any parts of the code marked as unstable
can change at any time. Please note that the unstable flag is applied to new experimental feature and internal classes only.
In future, new major versions will appear with breaking changes, including updated of minimum (peer) dependencies.