Ask Question

NextJS: How to exclude backend dependencies from the frontend bundle?

In my nextjs application, I sometimes want use backend dependencies inside my getServerSideProps or getInitialProps (if they are executed during server side rendering).

My problem is, that as soon as I import those dependencies in my page file, the nextjs build fails because some dependencies bound to nodejs couldn't be found in the browser for example:
Module not found: Can't resolve 'fs'

I also don't want to have those dependencies included in my frontend bundle therefore my current workaround is to require those dependencies only in the serverside code, so they aren't catched by the frontend webpack build, but directly required by nodejs on the serverside:

const userService = require('../../backend/services/user-service'); // eslint-disable-line @typescript-eslint/no-var-requires

const hasSocialLogin = userService.hasSocialLogin(req.user);

But this is not optimal, because now I have no TypeScript support for the typings of my UserService.

NextJSReactwebpackTypeScript

10150 views

Authorยดs Dominik Sumer image

Dominik Sumer

๐Ÿ‘
1
Last edited on

2 Answers

Best answer

I found a sustainable solution for this! Via the next.config.js file you can modify the webpack configuration of nextjs, and for example add an IgnorePlugin which ignores backend-specific dependencies in the frontend bundle.

Here an example:

module.exports = {
  webpack: (config, { isServer, webpack }) => {
    if (!isServer) {
      config.node = {
        dgram: 'empty',
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        child_process: 'empty',
      };

      config.plugins.push(new webpack.IgnorePlugin(/^(elastic-apm-node|bunyan)$/));
      config.plugins.push(
        new webpack.IgnorePlugin({
          checkResource(resource, context) {
            // If I am including something from my backend directory, I am sure that this shouldn't be included in my frontend bundle
            if (resource.includes('/backend/') && !context.includes('node_modules')) {
              return true;
            }
            return false;
          },
        }),
      );
    }

    return config;
  },
};

In the webpack section of your nextjs config, you can check if it is currently processing the frontend bundle, by checking is isServer is set to false. Then you can do some stuff, like disabling some nodejs specific dependencies (because they are not available in the browser).

I've also added a IgnorePlugin which removes some dependencies where I am sure that they only are needed in the backend (in my case all backend related code is placed at /backend/**), and should not be included in the frontend bundle. You can configure even more stuff with the IgnorePlugin when you for example use it with the checkResource configuration which is documented here: https://webpack.js.org/plugins/ignore-plugin/#using-filter-functions

๐Ÿ‘
1
๐Ÿš€
1
โค๏ธ
1
Authorยดs kannasuresh99 image
When I use this, I get a error. "Reference error: webpack is not defined". Should I install webpack as a dev-dependency and use it next.config.js?
Authorยดs Dominik Sumer image
no you don't have to install seperately. just make sure that your function arguments look like this: webpack: (config, { isServer, webpack }) => { .. then it should be able to resolve the webpack variable successfully