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.
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 }), | |
| } | |
| } |