4

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.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Tim Van Laer
  • 2,434
  • 26
  • 30

1 Answers1

6

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
Tim Van Laer
  • 2,434
  • 26
  • 30