pg-mem icon indicating copy to clipboard operation
pg-mem copied to clipboard

Importing pg-mem in my Next.js project fails trying to import @mikro-orm/mongodb

Open gthb opened this issue 2 years ago • 2 comments

Describe the bug

Just trying to use pg-mem in a Next.js app (importing pg-mem in our in-house library that is used in our Next.js app), the Next.js app fails to start in both dev and prod mode, with this:

error - ../Apiary/node_modules/@mikro-orm/core/utils/Configuration.js:237:13
Module not found: Can't resolve '@mikro-orm/mongodb'

Import trace for requested module:
../Apiary/node_modules/@mikro-orm/core/utils/index.js
../Apiary/node_modules/@mikro-orm/core/index.js
../Apiary/node_modules/pg-mem/index.js
[...]

I am, of course, not trying to use anything involving MongoDB :) — nor actually anything involving an ORM, so ideally this failing import would not be reached in the first place.

To Reproduce

In a Next.js app (I'm in Next.js 12.1.0), just try to import pg-mem:

import { newDb } from 'pg-mem';

(but I don't know, the problem might only manifest if this import is in an ES-module library imported by your Next.js app rather than directly in the Next.js app ... and the library might need to be npm-linked to your application)

... and either npm run build or npm run dev, the above failed module resolution happens either way.

pg-mem version

2.4.3

gthb avatar May 30 '22 00:05 gthb

As a workaround, I added this to the webpack configuration function in next.config.js:

    config.plugins.push(
      new IgnorePlugin({
        resourceRegExp: /^@mikro-orm\/|^knex|typeorm|slonik|pg-promise/,
        contextRegExp: /pg-mem/,
      })
    );

and of course the import of that plugin up top:

const { IgnorePlugin } = require('webpack');

and that got me past this, so I can start prototyping use of pg-mem in my app.

gthb avatar May 30 '22 13:05 gthb

I had the same problem with Next 14.0. The syntax provided by @gthb didn't work for me. Here is the workaround I found. I also use node-mocks-http, so some of the modules are probably useless for pg-mem only.

const nextConfig = {
  reactStrictMode: true,
  webpack: (config) => {
    config.resolve.fallback = {
      fs: false,
      net: false,
      tls: false,
      typeorm: false,
      slonik: false,
      'pg-promise': false,
      knex: false,
      dns: false,
      '@mikro-orm/core': false,
      '@mikro-orm/postgresql': false,
      kysely: false
    };
    return config;
  }
};

module.exports = nextConfig;

The resolve.fallback specifies how Webpack should handle modules that cannot be found in the standard resolution paths. If you use this config, you're certain those modules won't be needed in the browser (I guess it is 99.99% of the cases).

If you need it in client-side, you can specify to webpack how to resolve the module that are not found:

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  webpack: (config) => {
    config.resolve.fallback = {
      fs: require.resolve('fs'),
      net: require.resolve('net'),
      // Same for all modules you need
    };
    return config;
  }
};

module.exports = nextConfig;

This second config includes what we call "polyfills", allowing the module usage in a browser-like environment. More info here : https://webpack.js.org/configuration/resolve/#resolvefallback

Hope it helps

nboyet avatar Mar 17 '24 09:03 nboyet