Tim Van Laer
Tim Van Laer

Reputation: 2534

How to include static files into the lambda package with AWS SAM esbuild?

I have a NodeJS AWS Lambda function which generates an e-mail based on a html template file (emailTemplate.html). I started building my lambdas with esbuild via SAM. Now I wonder how I can configure SAM/esbuild to include this file into my lambda package.

This is the SAM template configuration for the lambda:

  EmailNotificationFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./lambdas-node/email-notifications/
      Handler: daily-summary.handler
      Timeout: 120
      MemorySize: 512
      Runtime: nodejs16.x
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Sourcemap: true
        EntryPoints:
          - daily-summary.ts

In my application code, I read the file from the local file system:

fs.readFileSync("./emailTemplate.html", "utf-8")

The html file is small so I'd like to stick to this minimalistic approach. I can always fetch the file from S3 or package it in a layer but I prefer not to go there.

Upvotes: 7

Views: 5894

Answers (1)

Tim Van Laer
Tim Van Laer

Reputation: 2534

Ok, so basically ESBuild's file loader is the way to go. ESBuild will replace the import with a reference to the file and copy over the file to the result bundle. (That's exactly what I wanted.)

This behaviour seems rather specific to ESBuild and will not work with the regular tsc compiler. So I replaced my build step to typechecking with tsc and transpiling with esbuild (see below)

I added an import to the html file to my code. This will ESBuild trigger to do something with this file.

import emailTemplateHtmlUrl from "./emailTemplate.html";

To keep the typechecker happy, I added also a types.d.ts file (mind the d.ts extension)

declare module '*.html' {
  const value: string;
  export default value
}

And then I added the Loader to my SAM template so that ESBuild will copy over html files and reference them in the import:

  EmailNotificationFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./lambdas-node/email-notifications/
      Handler: daily-summary.handler
      Timeout: 120
      MemorySize: 512
      Runtime: nodejs16.x
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Sourcemap: true
        Loader:
          - .html=file
        EntryPoints:
          - daily-summary.ts

And finally, my new test command looks now like this:

tsc --noEmit
npx esbuild daily-summary.ts --outdir=. --loader:.html=file --platform=node 
--bundle
mocha *.spec.js

Upvotes: 11

Related Questions