1

I am new to AWS and trying to deploy a GraphQL API written in NodeJS as an AWS Lambda using Serverless. I have followed several tutorials that are close to what I am doing but cannot get the handler to work. The closest tutorial to what I am doing was using JavaScript, where I am using TypeScript. I followed closely but using TypeScript. I am getting errors that it cannot find the handler module (Error: Cannot find module 'lambda').

My handler file is named lambda.ts looks like this `

import {app} from './app';
import {serverless} from 'serverless-http';

export const handler = serverless(app);

`

My serverless.yml looks like this `

service: graphql-api

frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs12.x
  region: us-east-1
functions:
  serverlessApi:
    handler: lambda.handler

app.ts

import express from 'express';
import cors from 'cors';
import { graphqlHTTP } from 'express-graphql';
import { schema, resolvers } from './api-schema/';
import { loginMiddleware } from './login-middleware';

const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(loginMiddleware);
app.use(
    '/graphql',
    graphqlHTTP({
        schema: schema,
        graphiql: true,
        rootValue: resolvers,
    })
);

export default app;

` The lambda.js, app.ts, and serverless.yml files are all in the same root directory.

I have tried to convert the code to JavaScript and get errors that it cannot find the 'app' module. (Cannot find module './app')

lambda.js and looks like this `

const app = require('./app');
const serverless = require('serverless-http');

module.exports.handler = serverless(app);

`

I have also tried to export 'app' as default or named getting the same result. I am out of ideas. Any help is much appreciated.

2 Answers2

1

Still have no solution to the issue after several changes. I did upgrade to Node16, but more importantly, I followed the documentation here: https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-aws-lambda#deployment-using-serverless-webpack The npm package serverless-esbuild started me in the right direction, but it had issues with prisma. I don't like having to use webpack, and I am still getting a CORS error, but the original issue of not finding the module is fixed. Also changed my handler file to look like this:

import app from './app';
import serverless from 'serverless-http';

const handler = () => {
    return serverless(app);
}
export { handler };

I was surprised to see the difference in the webpack build and the esbuild. esbuild is 1.2 MB, where the webpack build is 96 MB! Subsequent runs hit the aws max at around 200MB and failed to upload. It also takes at least 2x as long to complete. I am considering looking at alternatives to serverless as it seems to be tough to configure for what I have to think is a basic graphql implementation.

0

The problem likely stems from the fact that you're mixing JS and TS here. I don't see you using TypeScript really in app.ts, so to keep things simple, I would recommend switching to pure js for now to make things work, and then switching to TS.

You're also using ESM, that is not supported in nodejs12.x runtime, and mixing ESM and CommonJS (your lambda.js is using CommonJS) can cause some troubles, so I would suggest to switch the app.js implementation to use requires instead of imports and export in CommonJS style, at least in initial iteration.

You can also safely upgrade to nodejs16.x runtime, as nodejs12.x is going to be deprecated soon.

If you'd like to stick to TypeScript and/or ESModules, you'll need a plugin like https://www.npmjs.com/package/serverless-esbuild and I would recommend to do so, after successfully deploying the initial version.

pgrzesik
  • 1,869
  • 13
  • 14
  • I think you are right but I need to go in the direction of typescript since my whole app is typescript. Also I have a server.ts file that needs to consume the app ts module also. I'll try upgrading to node 16. I noticed the old version but thought since the template was generated by server less it must be right. Any additional tips on using serverless-esbuild? – user3349255 Nov 19 '22 at 20:26
  • It's hard to provide more suggestions in this small thread but if that's the case, I recommend sticking with TS from the start. No additional tips for `serverless-esbuild`, its documentation is pretty good, it should work out of the box for usual cases. – pgrzesik Nov 21 '22 at 12:24