Skip to content

Instantly share code, notes, and snippets.

@adieuadieu
Last active January 25, 2022 03:36
Show Gist options
  • Save adieuadieu/8ef0032714889f0af42f0afae3092789 to your computer and use it in GitHub Desktop.
Save adieuadieu/8ef0032714889f0af42f0afae3092789 to your computer and use it in GitHub Desktop.
Using esbuild in your Serverless Framework Project

Using esbuild in your Serverless Framework Project

How to use esbuild to transpile and bundle your TypeScript Lambda functions in a Serverless Framework project - all without using any plugins!

Example source code from article Using esbuild in your Serverless Framework Project.

const fs = require('fs')
const cloudformationSchema = require('@serverless/utils/cloudformation-schema')
const esbuild = require('esbuild')
const yaml = require('js-yaml')
const rimraf = require('rimraf')
const SERVERLESS_YML_PATH = './serverless.yml'
const OUT_DIR = './dist'
// ref: https://esbuild.github.io/api/#simple-options
const ESBUILD_CONFIG = {
bundle: true,
external: ['aws-sdk'],
format: 'cjs',
minify: true,
platform: 'node',
outbase: 'src',
outdir: OUT_DIR,
}
async function getConfig() {
return yaml.loadAll(fs.readFileSync(SERVERLESS_YML_PATH), {
schema: cloudformationSchema,
})[0]
}
;(async function main() {
rimraf.sync(OUT_DIR)
const { functions, provider } = await getConfig()
const handlers = Object.entries(functions)
.map(([, fn]) => fn.handler.replace('dist/', 'src/'))
.map((fn) => {
const parts = fn.split('.')
const path = parts.slice(0, parts.length - 1).join('.')
return fs.existsSync(path + '.ts') ? path + '.ts' : path + '.js'
})
console.info('Building handlers..')
await esbuild
.build({
...ESBUILD_CONFIG,
entryPoints: handlers,
target: provider.runtime
? 'node' + provider.runtime.match(/\d+/g)[0]
: 'node14',
})
.catch(() => process.exit(1))
handlers.map((handler) => {
const bundlePath = handler.replace('.ts', '.js').replace('src/', 'dist/')
const stat = fs.statSync(bundlePath)
console.log(
bundlePath,
'-',
+(stat.size / 1024 / 1024).toPrecision(3),
'MB',
)
})
})()
{
"name": "example",
"scripts": {
"build": "node build.js",
"predeploy": "npm run build",
"deploy": "serverless deploy"
},
"devDependencies": {
"@types/aws-lambda": "8.10.83",
"esbuild": "0.12.22",
"js-yaml": "4.1.0",
"serverless": "2.55.0",
"rimraf": "3.0.2",
"typescript": "4.3.5"
}
}
service: example
provider:
name: aws
runtime: nodejs14.x
package:
excludeDevDependencies: false
patterns:
- '!./**'
- './dist/**'
functions:
example:
description: An example lambda function
handler: dist/example.handler
memorySize: 256
events:
- http: GET /example
// Save as: src/example.ts
import * as AWSLambda from 'aws-lambda'
export default async function exampleHandler(
event: AWSLambda.APIGatewayProxyEvent,
context: AWSLambda.Context,
): Promise<AWSLambda.APIGatewayProxyStructuredResultV2> {
return {
statusCode: 200,
body: JSON.stringify({ event, context }),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment