6

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.

Bijin Abraham
  • 1,709
  • 2
  • 11
  • 25
Naldo Sales
  • 61
  • 1
  • 1
  • 2
  • 1
    if you are trying to use it in the browser side, it won’t work, because it is a nodejs library. – luisbar May 11 '21 at 02:18
  • you need an isomorphic library, but for fs I think that it does not exists, [this link explain about building an isomorphic package](https://hackernoon.com/building-isomorphic-javascript-packages-1ba1c7e558c5) – luisbar May 11 '21 at 02:21
  • Related: https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application – Ciro Santilli OurBigBook.com Dec 15 '21 at 11:49

3 Answers3

16

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/

Marcin Wosinek
  • 793
  • 3
  • 8
1

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

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

},

0

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;