nitro icon indicating copy to clipboard operation
nitro copied to clipboard

Cannot find module lodash/isNil imported from recharts in production since nitro v3

Open ulrichstark opened this issue 1 month ago • 4 comments

Environment

Node: 24.10.0 Vite: 7.2.2 Nitro: 3.0.1-alpha.1 and nitro-nightly 3.0.1-20251117-115950-87e718da

Reproduction

Repro project: https://github.com/ulrichstark/nitro-repro-cant-find-module-lodash-isnil

Reproduction commands:

git clone https://github.com/ulrichstark/nitro-repro-cant-find-module-lodash-isnil
cd nitro-repro-cant-find-module-lodash-isnil
npm i
npm run build
node .output/server/index.mjs

Then go to http://localhost:3000

Describe the bug

SInce upgrading to nitro v3, our application crashes with the following message in production when navigating to a route importing recharts. It works in nitro v2 and in nitro v3 when running in local dev env.

Additional context

The error message points me to the missing file extension as the cause for this issue. But why is that causing issues since nitro v3 and hasn't caused any issues before? We were using Tanstack with @tanstack/nitro-v2-vite-plugin before. Or is that rather an issue of Vite / my config?

Logs

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/ulrichstark/Desktop/matt-home/.output/server/node_modules/lodash/isNil' imported from /Users/ulrichstark/Desktop/matt-home/.output/server/chunks/_/index-eP4z4deI.mjs
Did you mean to import "lodash/isNil.js"?
    at finalizeResolution (node:internal/modules/esm/resolve:274:11)
    ... 6 lines matching cause stack trace ...
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
  cause: Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/ulrichstark/Desktop/matt-home/.output/server/node_modules/lodash/isNil' imported from /Users/ulrichstark/Desktop/matt-home/.output/server/chunks/_/index-eP4z4deI.mjs
  Did you mean to import "lodash/isNil.js"?
      at finalizeResolution (node:internal/modules/esm/resolve:274:11)
      at moduleResolve (node:internal/modules/esm/resolve:864:10)
      at defaultResolve (node:internal/modules/esm/resolve:990:11)
      at #cachedDefaultResolve (node:internal/modules/esm/loader:757:20)
      at ModuleLoader.resolve (node:internal/modules/esm/loader:734:38)
      at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:317:38)
      at #link (node:internal/modules/esm/module_job:208:49)
      at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
    code: 'ERR_MODULE_NOT_FOUND',
    url: 'file:///Users/ulrichstark/Desktop/matt-home/.output/server/node_modules/lodash/isNil'
  },
  status: 500,
  statusText: undefined,
  headers: undefined,
  data: undefined,
  body: undefined,
  unhandled: true
}

ulrichstark avatar Nov 17 '25 13:11 ulrichstark

nitro plugin options add noExternals: true

zouhangwithsweet avatar Nov 19 '25 01:11 zouhangwithsweet

nitro plugin options add noExternals: true

Thanks! That fixes the issue for me. But is this the expected configuration to handle this issue or just a workaround for an issue in nitro?

Edit: setting this to true breaks HMR in development. Therefore i made the value of noExternals depend on whether vite is running in production or not.

Edit 2: HMR seems to be broken in general in TanStack Start if using nitro v3 plugin: https://github.com/TanStack/router/issues/5904

ulrichstark avatar Nov 19 '25 10:11 ulrichstark

nitro plugin options add noExternals: true

Thanks! That fixes the issue for me. But is this the expected configuration to handle this issue or just a workaround for an issue in nitro?

Edit: setting this to true breaks HMR in development. Therefore i made the value of noExternals depend on whether vite is running in production or not.

I did the following, which worked too, and is more fine-grained:

ssr: {
    noExternal: ['lodash'],
},

jonasfroeller avatar Nov 20 '25 01:11 jonasfroeller

nitro plugin options add noExternals: true

Thanks! That fixes the issue for me. But is this the expected configuration to handle this issue or just a workaround for an issue in nitro? Edit: setting this to true breaks HMR in development. Therefore i made the value of noExternals depend on whether vite is running in production or not.

I did the following, which worked too, and is more fine-grained:

ssr: {
    noExternal: ['lodash'],
},

Thanks, but your configuration doesn't fix my issue. The following configuration fixes the issue in my repro project:

ssr: {
    noExternal: ["recharts", "recharts-scale", "decimal.js-light"],
}

ulrichstark avatar Nov 20 '25 10:11 ulrichstark