What is the proper way to require node modules within next.js /api function handler

Viewed 575

I am trying to require bcrypt inside a file within my /api folder.

// pages/api/login.js
const bcrypt = require('bcrypt');

export default async function handler(req, res) {
  switch (req.method) {
    case 'POST':
      // do stuff with bcrypt
      res.status(200).json()
      break
    default:
      res.status(405).end() //Method Not Allowed
      break
  }
}

Everything works fine when I use npm run dev but when I run npx serverless I get this error:

ModuleNotFoundError: Module not found: Error: Can't resolve 'mock-aws-s3'

After a lot of research it seems this is happening because webpack is trying to include bcrypt in the client-side bundle when it should only be included in the server-side. I don't understand why this happens because according to the Next.js docs:

Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a page. They are server-side only bundles and won't increase your client-side bundle size.

I found a workaround to this problem by using eval

const bcrypt = eval("require('bcrypt')");

but this feels very hacky and like I am not understanding next.js properly. What is the proper way to handle this situation and why is webpack trying to include the files within /api?

1 Answers

I've faced this problem earlier, make sure that you include both node_modules folder and package.json files in your serverless config file. If you exclude either one of them, it will throw the above mentioned error.

EDIT: @tarandeept Here is a screenshot of my packages:

enter image description here

And here is my folder structure:

enter image description here

Related