A progressive Node.js framework for building efficient and scalable server-side applications.
Nest framework TypeScript starter repository.
yarn add @codegenie/serverless-express aws-lambda @nestjs/config
yarn add -D @types/aws-lambda serverless-offline serverless-webpack terser-webpack-plugin fork-ts-checker-webpack-plugin
# replace app-name
service: app-name
frameworkVersion: '3'
plugins:
- serverless-webpack
- serverless-offline
custom:
config: ${file(./config/${self:provider.stage}.env.json)}
webpack:
includeModules: true
forceExclude:
- aws-sdk
provider:
name: aws
deploymentMethod: direct
runtime: nodejs20.x
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'ap-southeast-1'}
environment: ${file(./config/${opt:stage, 'dev'}.env.json)}
# adjust bucket & vpc as needed
# deploymentBucket:
# name: bucket_name
# vpc:
# securityGroupIds:
# - sg-xxx
# subnetIds:
# - subnet-xxx
# - subnet-xxx
# - subnet-xxx
functions:
api:
handler: dist/main.handler
# adjust memory, storage, and timeout as needed.
# memorySize: 2048
# ephemeralStorageSize: 1024
# timeout: 25
events:
- httpApi: '*'
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
@Module({
// add config module to fetch env
imports: [ConfigModule.forRoot({ isGlobal: true })],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@codegenie/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';
let server: Handler;
async function bootstrapSLS(): Promise<Handler> {
const app = await NestFactory.create(AppModule);
await app.init();
const expressApp = app.getHttpAdapter().getInstance();
return serverlessExpress({ app: expressApp });
}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
export const handler: Handler = async (
event: any,
context: Context,
callback: Callback,
) => {
server = server ?? (await bootstrapSLS());
return server(event, context, callback);
};
if (process.env.NEST_ENV === 'HTTP') {
bootstrap();
}
{
"compilerOptions": {
...
"esModuleInterop": true
}
}
/* eslint-disable @typescript-eslint/no-var-requires */
const webpack = require('webpack');
const path = require('path');
const slsw = require('serverless-webpack');
const TerserPlugin = require('terser-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const lazyImports = [
'@nestjs/microservices',
'@nestjs/microservices/microservices-module',
'@nestjs/websockets/socket-module',
'@nestjs/platform-express',
'@grpc/grpc-js',
'@grpc/proto-loader',
'kafkajs',
'mqtt',
'nats',
'ioredis',
'amqplib',
'amqp-connection-manager',
'pg-native',
'cache-manager',
'class-validator',
'class-transformer',
];
module.exports = {
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
devtool: 'source-map',
entry: slsw.lib.entries,
target: 'node',
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
libraryTarget: 'commonjs2',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
externals: {
// add package to be excluded in bundle, example:
// argon2: 'commonjs argon2',
},
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader',
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true,
},
},
],
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
keep_classnames: true,
},
}),
],
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
new webpack.IgnorePlugin({
checkResource(resource) {
if (lazyImports.includes(resource)) {
try {
require.resolve(resource);
} catch (err) {
return true;
}
}
return false;
},
}),
],
};
.serverless
.webpack
.env*
*.env.json
config/
┣ dev.env.json
┗ prod.env.json
{
"start:sls": "nest build && serverless offline start",
"deploy:dev": "nest build && serverless deploy -s dev",
"deploy:prod": "nest build && serverless deploy -s prod"
}
You can run the app either by serverless offline or normal server.
yarn start:sls
Make sure to add this value to .env file
NEST_ENV = "HTTP"
then run
yarn start:dev
yarn deploy:dev
- https://www.brymartinez.blog/deploying-nestjs-to-lambda-using-webpack/
- https://johnny.sh/blog/concise-guide-to-nestjs-on-lambda/
- https://programoholic.medium.com/build-and-deploy-serverless-application-with-webpack-584163367390
- https://www.prisma.io/docs/orm/prisma-client/deployment/serverless/deploy-to-aws-lambda