Cache handler ERR_MODULE_NOT_FOUND when using ESM modules
hdodov opened this issue · 1 comments
Link to the code that reproduces this issue
https://github.com/hdodov/test-nextjs/tree/cache-handler-not-working
To Reproduce
- Clone the repo https://github.com/hdodov/test-nextjs/tree/cache-handler-not-working
npm i
npm run dev
- You'll see the error
Current vs. Expected behavior
I have "type": "module"
in my package.json
, so I can't add the cache handler like this, as the docs suggest:
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
}
Instead, I need to add it like this:
module.exports = {
- cacheHandler: require.resolve('./cache-handler.js'),
+ cacheHandler: import.meta.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
}
However, when I do so, I get the following error on npm run dev
:
$ npm run dev
> test-nextjs@0.1.0 dev
> next dev
▲ Next.js 15.1.0
- Local: http://localhost:3000
- Network: http://192.168.100.16:3000
✓ Starting...
✓ Ready in 1625ms
[Error: Cannot find module '/Users/hristiyan.dodov/Projects/test-nextjs/.next/file:/Users/hristiyan.dodov/Projects/test-nextjs/cache-handler.js' imported from /Users/hristiyan.dodov/Projects/test-nextjs/node_modules/next/dist/server/next-server.js] {
code: 'ERR_MODULE_NOT_FOUND',
url: 'file:///Users/hristiyan.dodov/Projects/test-nextjs/.next/file:/Users/hristiyan.dodov/Projects/test-nextjs/cache-handler.js'
}
…and I also get it if I try npm run build
directly:
$ npm run build
> test-nextjs@0.1.0 build
> next build
▲ Next.js 15.1.0
Creating an optimized production build ...
✓ Compiled successfully
✓ Linting and checking validity of types
> Build error occurred
[Error: Cannot find module '/Users/hristiyan.dodov/Projects/test-nextjs/file:/Users/hristiyan.dodov/Projects/test-nextjs/cache-handler.js' imported from /Users/hristiyan.dodov/Projects/test-nextjs/node_modules/next/dist/export/helpers/create-incremental-cache.js] {
type: 'Error',
code: 'ERR_MODULE_NOT_FOUND',
url: 'file:///Users/hristiyan.dodov/Projects/test-nextjs/file:/Users/hristiyan.dodov/Projects/test-nextjs/cache-handler.js'
}
Check these two branches:
- https://github.com/hdodov/test-nextjs/tree/cache-handler-working — cache handler works here
- https://github.com/hdodov/test-nextjs/tree/cache-handler-not-working — here it doesn't
Here's a diff between the two: hdodov/test-nextjs@cache-handler-working...cache-handler-not-working
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 23.6.0: Thu Sep 12 23:34:49 PDT 2024; root:xnu-10063.141.1.701.1~1/RELEASE_X86_64
Available memory (MB): 32768
Available CPU cores: 16
Binaries:
Node: 20.17.0
npm: 10.8.2
Yarn: N/A
pnpm: 9.15.0
Relevant Packages:
next: 15.1.0 // Latest available version is detected (15.1.0).
eslint-config-next: 15.1.0
react: 19.0.0
react-dom: 19.0.0
typescript: 5.7.2
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Module Resolution
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local)
Additional context
No response
I logged the difference between require.resolve
and import.meta.resolve
:
console.log(require.resolve("./cache-handler.js"));
// /Users/hristiyan.dodov/Projects/test-nextjs/cache-handler.js
console.log(import.meta.resolve("./cache-handler.js"));
// file:///Users/hristiyan.dodov/Projects/test-nextjs/cache-handler.js
It seems that file://
should be removed.
Also, the file should be cache-handler.cjs
, rather than cache-handler.js
. Otherwise you get this error:
ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/Users/hristiyan.dodov/Projects/test-nextjs/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at <unknown> (cache-handler.js:5:1)
Here's the fix: hdodov/test-nextjs@b0f3757
const nextConfig = {
cacheHandler: import.meta.resolve("./cache-handler.cjs").replace("file://", ""),
cacheMaxMemorySize: 0,
};
However, I think that Next.js should handle this more adequately or at least put it in the docs…