Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails in Next.js app/ directory incl. with API Route Handlers #979

Closed
karlhorky opened this issue Feb 27, 2023 · 36 comments
Closed

Fails in Next.js app/ directory incl. with API Route Handlers #979

karlhorky opened this issue Feb 27, 2023 · 36 comments

Comments

@karlhorky
Copy link

What went wrong?

Using bcrypt within a Route Handler in Next.js (API Route Handler within the new app/ directory) causes the app to crash with unusual errors:

error - ./node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <!doctype html>
| <html>
| <head>

Import trace for requested module:
./node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
./node_modules/@mapbox/node-pre-gyp/lib/ sync ^\.\/.*$
./node_modules/@mapbox/node-pre-gyp/lib/node-pre-gyp.js
./node_modules/bcrypt/bcrypt.js
./app/api/route.ts

I also reported over here in the Next.js repo:

What did you expect to happen?

bcrypt should work in the app/ directory, including in Route Handlers

Which version of nodejs and OS?

    Operating System:
      Platform: linux
      Arch: x64
      Version: Ubuntu 20.04.0 LTS Mon Feb 27 2023 14:52:57 GMT+0100 (Central European Standard Time)
    Binaries:
      Node: 16.14.2
      npm: 7.17.0
      Yarn: 1.22.19
      pnpm: 7.13.6
    Relevant packages:
      next: 13.2.2-canary.1
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0

If you find a bug, please write a failing test.

Ok, maybe once I find out more.

@karlhorky
Copy link
Author

Reading this issue in the bcrypt repo over here, it made me think that webpack maybe should not be used to try to bundle bcrypt... 🤔

So it occurred to me that maybe I should be using an externals webpack config and marking bcrypt as external:

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
+  webpack: (config) => {
+    config.externals = [...config.externals, 'bcrypt'];
+    return config;
+  },
};

module.exports = nextConfig;

Which indeed works (does not work on StackBlitz because the native module does run there):

CodeSandbox demo: https://codesandbox.io/p/sandbox/gracious-bose-wn2731?file=%2Fnext.config.js

Screenshot 2023-02-27 at 16 11 48

@karlhorky
Copy link
Author

Closing this out here and continuing the discussion over in the Next.js repo:

@fullStackDataSolutions
Copy link

fullStackDataSolutions commented Aug 10, 2023

I tried that, I got this error:

./node_modules/next-auth/core/init.js (10:14)
Module not found: Can't resolve 'crypto'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/next-auth/core/index.js
./node_modules/next-auth/next/index.js
./node_modules/next-auth/index.js
./app/api/auth/[...nextauth]/route.ts

@ibrahimullah12
Copy link

I had the same problem. The problem was solved by installing and importing. Instead of bcrypt install bcryptjs.

> npm i bcryptjs 

> npm i -D @types/bcryptjs

@daneseuwu
Copy link

I'm integrating authentication with nextauth v5 in nextjs 14.0.4 with prisma and I just got the error, I don't know, but bcryptjs worked instead of bcrypt

@breno404
Copy link

I'm a little scared to install bcryptjs because its last publication was 7 years ago and there are at least 40 issues open

@0rogerinho
Copy link

This error happens when you run bcrypt on the client side, to correct it if you don't want to use it on the client side but the error is still returning, check that all the places where you are using bctypt have "use server"

@umair-mirza
Copy link

Issue is still not resolved with Next.js 14.0. Still getting the error while using Client component

@xcodewhisperer
Copy link

Same error with argon2. I'm looking for a workaround

@mohamed-younes16
Copy link

I had the same problem. The problem was solved by installing and importing. Instead of bcrypt install bcryptjs.

> npm i bcryptjs 

> npm i -D @types/bcryptjs

thank you it worked

@razzededge
Copy link

Same error with argon2. I'm looking for a workaround

I'm on the same boat... got error with argon2

@umair-mirza
Copy link

umair-mirza commented Feb 17, 2024

Finally got around the issue. Here's how you can fix this:

First, in next.config.js

push bcrypt to config.externals like so:

  webpack: (config) => {
    config.externals = [...config.externals, "bcrypt"];
    return config;
  },

Then where ever you are using bcrypt,

instead of importing it in the traditional way (import bcrypt from 'bcrypt')

You need to import it like so:

const bcrypt = require("bcrypt");

And make sure to put it above the line where it's being used. For example,

    const bcrypt = require("bcrypt");

    const hashedPassword = await bcrypt.hash(password, 12);

@token-ed
Copy link

@umair-mirza Thanks brother.

@udayprakash80
Copy link

Thanks @umair-mirza .. great man

@hariyebk
Copy link

hariyebk commented Apr 5, 2024

@umair-mirza 🙏🏻

@Olaw2jr
Copy link

Olaw2jr commented Apr 15, 2024

I'm integrating authentication with nextauth v5 in nextjs 14.0.4 with prisma and I just got the error, I don't know, but bcryptjs worked instead of bcrypt

Could you let me know if you were able to get this resolved?

@mikhatanu
Copy link

Hello. i'm encountering this problem in next js 14 middleware. Any solution?

@nin-o
Copy link

nin-o commented Apr 18, 2024

For me the solution was to use:
import { signIn } from 'next-auth/react';
instead of:
import { signIn } from '@/auth';

@razzededge
Copy link

razzededge commented Apr 18, 2024

For me the solution was to use: import { signIn } from 'next-auth/react'; instead of: import { signIn } from '@/auth';

You will not get custom event handlers etc this way, also you are importing client side only code and @/auth means your custom auth implementation which you changed to one delivered with the next-auth package - if this solves your particular case, then fine - but I would advise against it in most cases as the problem within this thread is that it doesn't work on server side components

@theogenejr
Copy link

Tried all solution. The one using bcryptjs instead of bcrypt worked just fine for me.
npm i bcryptjs
npm i -D @types/bcryptjs

@pulgueta
Copy link

pulgueta commented May 3, 2024

Still have the same issue for bcrypt, argon2, @node-rs/bcrypt and @node-rs/argon2 on Next.js 14.2.3. Set the serverComponentExternalPackages for all 4 of these packages and the Webpack configuration but still no solution. Had to use bcryptjs for now.

@ezeparziale
Copy link

I'm integrating authentication with nextauth v5 in nextjs 14.0.4 with prisma and I just got the error, I don't know, but bcryptjs worked instead of bcrypt

I replaced bcrypt with bcryptjs, and everything works okay.

Running with:

  • nextauth 5.0.0-beta.17
  • nextjs 14.1.3

@pulgueta
Copy link

pulgueta commented May 9, 2024

I'm integrating authentication with nextauth v5 in nextjs 14.0.4 with prisma and I just got the error, I don't know, but bcryptjs worked instead of bcrypt

I replaced bcrypt with bcryptjs, and everything works okay.

Running with:

  • nextauth 5.0.0-beta.17
  • nextjs 14.1.3

Me too. Used bcryptjs and works well but super slow.

@hoanglq
Copy link

hoanglq commented May 10, 2024

Instead of using bcrypt, we should use bcryptjs.
Here is my approach, you can try to solve the issue:

//const bcrypt = require("bcrypt");
var bcrypt = require('bcryptjs');

//...your codes
//const passwordsMatch = await bcrypt.compare(password, user.password);
const passwordsMatch = await bcrypt.hashSync(password, user.password);

@muhammadkeyton
Copy link

Hey guys this is a known issue with bcrypt, bcrypt is a native module and when nextjs tries to import it in the client side, this error happens, a simple fix is to make the file where you are importing and using bcrypt to be a server file, add the ' use server' at the top,this should fix it, it worked for me

@ezeparziale
Copy link

I'm integrating authentication with nextauth v5 in nextjs 14.0.4 with prisma and I just got the error, I don't know, but bcryptjs worked instead of bcrypt

I replaced bcrypt with bcryptjs, and everything works okay.
Running with:

  • nextauth 5.0.0-beta.17
  • nextjs 14.1.3

Me too. Used bcryptjs and works well but super slow.

After several attempts, I managed to get bcrypt working with auth.js v5.0.0-beta.17.

The key lies in performing the bcrypt.compare operation in the auth.ts file, where it operates without issues, as opposed to placing it within the auth.config.ts file, where it fails.

The auth.ts file must be with the {...authConfig + providers}, this way it works 100% with bcrypt.

Example: https://github.com/ezeparziale/quark/blob/main/src/auth.ts

@mawiramawira
Copy link

mawiramawira commented Jun 24, 2024

webpack: (config) => {
config.externals = [...config.externals, "bcrypt"];
return config;
},

works for @node-rs/argon2 as well. add it to dependencies, install and import using require syntax

@LabelMinsk
Copy link

LabelMinsk commented Jun 27, 2024

Use it.
Custom generate hash and if you got after build trouble with trust host, set in your .env AUTH_TRUST_HOST=http://localhost:3000

custom by crypto module

 export async function isValidPassword(password: string, hashedPassword: string) {
    return (await hashPassword(password)) === hashedPassword;
}

export async function hashPassword(password:string){

    const arrayBuffer = await crypto.subtle.digest(
        "SHA-512",
        new TextEncoder().encode(password)
    )
    return Buffer.from(arrayBuffer).toString('base64')
}

@drilon305
Copy link

For me problem solved: 'use server' instead of 'use client' in a component.

@Bro3Simon
Copy link

This error happens when you run bcrypt on the client side, to correct it if you don't want to use it on the client side but the error is still returning, check that all the places where you are using bctypt have "use server"

Thanks, this helped me out!

Scenario: I moved my function that uses bycript to a utilities file that had both client and server functions. Even though I only ever called it on the server, it still produced the error during the build.

Fix: I moved all server utility functions to their own file under the api folder. Since it only had server functions, I didn't need to use use server directive. Perhaps the file being under the api folder also has something to do with not needing the use use server directive.

@FranckWebPro
Copy link

Finally got around the issue. Here's how you can fix this:

First, in next.config.js

push bcrypt to config.externals like so:

  webpack: (config) => {
    config.externals = [...config.externals, "bcrypt"];
    return config;
  },

Then where ever you are using bcrypt,

instead of importing it in the traditional way (import bcrypt from 'bcrypt')

You need to import it like so:

const bcrypt = require("bcrypt");

And make sure to put it above the line where it's being used. For example,

    const bcrypt = require("bcrypt");

    const hashedPassword = await bcrypt.hash(password, 12);

Sadly I have an error which say "bcrypt is not defined" this way, has anyone else encountered this issue?"

@ahmad-elshowair
Copy link

I was facing similar error:
image

to solve I did the following:

  • replace bcrypt with bcryptjs
  • add the following code to next.config.mjs
	webpack: (config) => {
		config.externals = [...config.externals, "bcrypt"];
		return config;
	},

@chriskuech
Copy link

Looks like the issue occurs if you have a middleware that indirectly references bcrypt (even though the middleware should be running on the server).

@BertramYe
Copy link

BertramYe commented Aug 27, 2024

but what if I use the nextjs 15 rc with the turbo compiler, how can I config and use the bcrypt as the external dependencies? with the similar config here below?

webpack: (config) => {
		config.externals = [...config.externals, "bcrypt"];
		return config;
	},

@kulubaev
Copy link

kulubaev commented Oct 16, 2024

in my case this issue was resolved putting

use server; directive in the file where I used bcrypt
i believe the library intended to be used in server side not client

@Bessonov
Copy link

Bessonov commented Dec 2, 2024

My workaround for the issue with bcrypt and a (plain) webpack build: mapbox/node-pre-gyp#308 (comment). Not sure if it will work with Next.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests