Regression after updating to 22.12.0 (getting ERR_REQUIRE_CYCLE_MODULE)
Version
v22.12.0
Platform
Darwin oyvind-mac.local 24.1.0 Darwin Kernel Version 24.1.0: Thu Oct 10 21:03:11 PDT 2024; root:xnu-11215.41.3~2/RELEASE_ARM64_T6020 arm64
(also happens on Linux)
Subsystem
module loading
What steps will reproduce the bug?
It fails when trying to build Storybook stories in our repo. It ran fine with 22.11.0. I assume it is some weirdness in CJS / ESM mixing.
As this seems to fail in Storybook I'm not sure how easy it is to minimize the failing case for me unfortunately :-(
See output below
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
Code runs
What do you see instead?
yarn build-storybook @storybook/core v8.4.5
info => Cleaning outputDir: storybook-static info => Loading presets SB_CORE-SERVER_0002 (CriticalPresetLoadError): Storybook failed to load the following preset: ./.storybook/main.ts.
Please check whether your setup is correct, the Storybook dependencies (and their peer dependencies) are installed correctly and there are no package version clashes.
If you believe this is a bug, please open an issue on Github.
SB_CORE-SERVER_0002 (CriticalPresetLoadError): Storybook failed to load the following preset: ./node_modules/@storybook/addon-webpack5-compiler-babel/preset.js.
Please check whether your setup is correct, the Storybook dependencies (and their peer dependencies) are installed correctly and there are no package version clashes.
If you believe this is a bug, please open an issue on Github.
ReferenceError: module is not defined at file://./node_modules/@storybook/addon-webpack5-compiler-babel/preset.js:1:1 at ModuleJobSync.runSync (node:internal/modules/esm/module_job:395:35) at ModuleLoader.importSyncForRequire (node:internal/modules/esm/loader:329:47) at loadESMFromCJS (node:internal/modules/cjs/loader:1414:24) at Module._compile (node:internal/modules/cjs/loader:1547:5) at node:internal/modules/cjs/loader:1677:16 at Object.newLoader (./node_modules/esbuild-register/dist/node.js:2262:9) at extensions..js (./node_modules/esbuild-register/dist/node.js:4838:24) at Module.load (node:internal/modules/cjs/loader:1318:32) at Function._load (node:internal/modules/cjs/loader:1128:12)
More info:
at loadPreset (./node_modules/@storybook/core/dist/common/index.cjs:16477:13)
More info:
at loadPreset (./node_modules/@storybook/core/dist/common/index.cjs:16477:13)
at async Promise.all (index 2)
at async loadPresets (./node_modules/@storybook/core/dist/common/index.cjs:16487:55)
at async getPresets (./node_modules/@storybook/core/dist/common/index.cjs:16520:11)
at async buildStaticStandalone (./node_modules/@storybook/core/dist/core-server/index.cjs:35384:11)
at async withTelemetry (./node_modules/@storybook/core/dist/core-server/index.cjs:35757:12)
at async build (./node_modules/@storybook/core/dist/cli/bin/index.cjs:2555:3)
at async s.<anonymous> (./node_modules/@storybook/core/dist/cli/bin/index.cjs:2661:7)
WARN Failed to load preset: {"type":"presets","name":"/Users/oyvind/dev/webclient-app/node_modules/@storybook/addon-webpack5-compiler-babel/preset.js"} on level 1 Error [ERR_REQUIRE_CYCLE_MODULE]: Cannot require() ES Module ./node_modules/@storybook/addon-webpack5-compiler-babel/preset.js in a cycle. (from ./node_modules/@storybook/core/dist/common/index.cjs) at ModuleLoader.importSyncForRequire (node:internal/modules/esm/loader:315:15) at loadESMFromCJS (node:internal/modules/cjs/loader:1414:24) at Module._compile (node:internal/modules/cjs/loader:1547:5) at node:internal/modules/cjs/loader:1677:16 at Object.newLoader (./node_modules/esbuild-register/dist/node.js:2262:9) at extensions..js (./node_modules/esbuild-register/dist/node.js:4838:24) at Module.load (node:internal/modules/cjs/loader:1318:32) at Function._load (node:internal/modules/cjs/loader:1128:12) at TracingChannel.traceSync (node:diagnostics_channel:322:14) at wrapModuleLoad (node:internal/modules/cjs/loader:219:24) file:///Users/oyvind/dev/webclient-app/node_modules/@storybook/addon-webpack5-compiler-babel/preset.js:1 module.exports = require('./dist/preset.cjs'); ^
ReferenceError: module is not defined at file:///Users/oyvind/dev/webclient-app/node_modules/@storybook/addon-webpack5-compiler-babel/preset.js:1:1 at ModuleJobSync.runSync (node:internal/modules/esm/module_job:395:35) at ModuleLoader.importSyncForRequire (node:internal/modules/esm/loader:329:47) at loadESMFromCJS (node:internal/modules/cjs/loader:1414:24) at Module._compile (node:internal/modules/cjs/loader:1547:5) at node:internal/modules/cjs/loader:1677:16 at Object.newLoader (/Users/oyvind/dev/webclient-app/node_modules/esbuild-register/dist/node.js:2262:9) at extensions..js (/Users/oyvind/dev/webclient-app/node_modules/esbuild-register/dist/node.js:4838:24) at Module.load (node:internal/modules/cjs/loader:1318:32) at Function._load (node:internal/modules/cjs/loader:1128:12)
Node.js v22.12.0
Additional information
In 22.11.0 it runs fine
Thanks for reporting, it seems to do you have any reproducible steps? If not can you try running it with NODE_OPTIONS=--stack-trace-limit=50 environment variable to get more frames from the stack trace?
Also, I am not sure if this matches the version of addon-webpack5-compiler-babel that you are using, but it seems https://github.com/storybookjs/addon-webpack5-compiler-babel/blob/main/preset.js was renamed to .js, which is in conflict with the package.json type field it has ("type": "module" indicates that preset.js should be treated as ESM, but it is written in CJS, which triggers the ReferenceError: module is not defined error you are seeing), that looks like a bug of addon-webpack5-compiler-babel, so it is a bit strange that it used to work?
Looking at the code it seems like a combination of at least 2 bugs:
- addon-webpack5-compiler-babel using
"type": "module"but assumespreset.jscan still be CJS - esbuild-register relying on pirates, which monkey patches the Node.js CJS loader internals, and they assume
Module.prototype._compileonly takes two arguments, and only pass down the first two arguments from the patched version into the original version, but this method takes 3 arguments (the new one beingformat) now.
Together they triggered a cycle somehow. I feel that at least the pirates bug need to be fixed in their repo, we don't maintain strict compatibility for monkey patching internals in Node.js, at best we try to keep certain commonly patched methods are still patchable, but if users patch them incorrectly, like what's happening here, they are at their own risk..
I think locally, you can maybe try patching your ./node_modules/addon-webpack5-compiler-babel by reversing https://github.com/storybookjs/addon-webpack5-compiler-babel/commit/7d3379b69cf104aa04f3e7f57d489362531888ec, and then patching your ./node_modules/esbuild-register/dist/node.js so that in where it monkey patches the loader, it passes the correct third argument into the original version, and see if that fixes your issue, and if it does, the patches should be upstreamed to addon-webpack5-compiler-babel and/or pirates
Thanks for looking into this!
Renaming node_modules/@storybook/addon-webpack5-compiler-babel/preset.js to preset.cjs as suggested does seem to resolve the issue for me! I can open a PR in that repo with the change.
Thanks again for the swift reply :-)
There's something really weird here. According to the package's config, the file preset.js should never be loaded: https://github.com/storybookjs/addon-webpack5-compiler-babel/blob/014263d886370a09a88783257f911ad33db36502/package.json#L25-L33
@targos You may be looking at an old version of the package, it was renamed to preset.js with a corresponding package.json change in https://github.com/storybookjs/addon-webpack5-compiler-babel/commit/7d3379b69cf104aa04f3e7f57d489362531888ec that I mentioned.
Actually you are looking at the right version probably, but this is loaded by esbuild-register (which bundles pirates) which monkey-patches the resolution that probably makes it load the wrong file. So somehow the recent internal changes in 22 exposes the bug in esbuild-register and/or pirates which in turn exposes the bug in addon-webpack5-compiler-babel
Whew, thanks for reporting this, @osmestad, and for looking into it, @joyeecheung and @targos. I'm seeing the same issue with @storybook/addon-webpack5-compiler-swc and was at a bit of a loss. The preset.cjs rename workaround did not work for me, though, and instead, I resorted to patching the module to remove the module field from the package.json:
diff --git a/package.json b/package.json
index 43a416a49529d4fbe51faa6e42c18afa25bb52cf..8eca1c8741511c1cbc352bf56de991c5059a2937 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,6 @@
{
"name": "@storybook/addon-webpack5-compiler-swc",
"version": "1.0.5",
- "type": "module",
"description": "Adds SWC as a Webpack5 compiler to Storybook",
"keywords": [
"storybook-addons",
@osmestad I'm curious if you made any other changes in your patch. When I renamed the root preset.js, it seemed to break loading the preset altogether. I can include the output if it would help debug this, but I'm assuming it's pretty specific to how Storybook loads presets.
Thanks again y'all!
@jrolfs Same here - patching to rename preset.js didn't work, but removing the module type did the trick
We were having the same issues as @jrolfs with the @storybook/addon-webpack5-compiler-swc in combination with getAbsolutePath as described here.
We removed all the getAbsolutePath occurrences in the main.js and used the following for framework, addons and core:
addons: [
'@storybook/addon-essentials',
'storybook-addon-cookie',
'@storybook/addon-webpack5-compiler-swc',
],
core: {
options: {
lazyCompilation: true,
},
},
framework: '@storybook/react-webpack5',
When updating @storybook/addon-webpack5-compiler-babel from 3.0.3 to 3.0.5 the original issue here is resolved :-)