Naldo Sales
Naldo Sales

Reputation: 91

Module not found: Can't resolve 'fs' - NextJS

I'm trying to use node-jsencrypt with NextJS (tsx):

index.tsx

import JSEncrypt from 'node-jsencrypt';

package.json

"node-jsencrypt": "^1.0.0"

Log

error - ./node_modules/node-jsencrypt/index.js:2:0

Module not found: Can't resolve 'fs'

Notes: I didn't find the 'webpack.config.js' file, as I saw in some topics.

Upvotes: 9

Views: 34555

Answers (4)

Syed Muqeet Aqib
Syed Muqeet Aqib

Reputation: 11

I was also having the same issue, in my case I was using bcrypt library like below

import bcrypt from "bcrypt";

to hash my data.

I learned that Next JS does not allows Node JS packages or libraries which utilize Node JS packages like fs. Instead of using bcrypt library I found bcrypt.js library like below

import bcrypt from "bcryptjs";

which works fine on the browser so I go with that.

Upvotes: 0

In the next.config.js file add the code below

build: {
extend(config, {}) {
    config.node = {
        fs: 'empty'
    }
}

Upvotes: 1

Mucyo Christian
Mucyo Christian

Reputation: 101

I was also having the same issue when integrating sendGrid. However, I solved by adding a webpack property in next.config.js file like below:

const nextConfig = {
  reactStrictMode: true,
  webpack: (config) => {
    config.resolve = {
      ...config.resolve,
      fallback: {
        fs: false,
      },
    };
    return config;
  },
};

module.exports = nextConfig;

Upvotes: 3

Marcin Wosinek
Marcin Wosinek

Reputation: 1019

Ok, I played around with this issue & I think I have what cover all possible combinations. In the repo you can find working examples. There are 3 possible approaches, and the right one will depend on what's already in your project - details that were unspecified in the original question.

  1. Solution while using webpack 5 next.config.js
module.exports = {
  future: {
    webpack5: true, // by default, if you customize webpack config, they switch back to version 4. 
      // Looks like backward compatibility approach.
  },
  webpack(config) {
    config.resolve.fallback = {
      ...config.resolve.fallback, // if you miss it, all the other options in fallback, specified
        // by next.js will be dropped. Doesn't make much sense, but how it is
      fs: false, // the solution
    };

    return config;
  },
};
  1. Solution while using webpack 4 - next.config.js
module.exports = {
  webpack(config) { // we depend on nextjs switching to webpack 4 by default. Probably they will 
    // change this behavior at some future major version.
    config.node = {
      fs: "empty", // webpack4 era solution 
    };

    return config;
  },
};
  1. You could consider using other library. According to node-jsencrypt readme they are node port of jsencrypt, and here I assume you try to build for browser. The node library got stuck at version 1, while the original library is already at version 3. As I checked in the last commit on main, if you use this library, it's building just fine without any issues.

Original, nextjs unaware answer:

Since version 5, webpack doesn't include polyfiles for node libraries. In your case, you most likely need to add resolve.fallback.fs: false to your webpack config.

More about this option- https://webpack.js.org/configuration/resolve/#resolvefallback It mentioned in v4 to v6 migration guide, if this is your case: https://webpack.js.org/migrate/5/

Upvotes: 21

Related Questions