使用Nx运行Storybook时出现Webpack钩子错误的求助
问题重现
执行命令 nx run my-lib:storybook 启动Storybook时,触发以下Webpack错误:
webpack built preview 90be684218940772f424 in 162ms
Error: NormalModuleFactory.beforeResolve (IgnorePlugin) is no longer a waterfall hook, but a bailing hook instead. Do not return the passed object, but modify it instead. Returning false will ignore the request and results in no module created.
at .....
问题原因
这个错误确实和Webpack版本不兼容直接相关:Webpack 5重构了NormalModuleFactory.beforeResolve钩子的行为,将其从waterfall钩子改为bailing钩子。项目中某个依赖(旧版Storybook插件、Nx Webpack相关插件,或是自定义Webpack配置)仍在使用Webpack 4及更早版本的钩子写法——即返回修改后的对象,而非直接修改传入的参数,导致触发兼容性报错。
解决方案
1. 升级Nx与Storybook依赖到兼容版本
- 执行
nx migrate latest升级Nx核心依赖,完成后运行npm install或yarn install同步更新 - 确保
@storybook/react、@storybook/addon-*等Storybook包的版本与@nrwl/storybook版本匹配,建议统一升级到最新稳定版,避免版本错位导致的Webpack钩子冲突
2. 修正自定义Webpack配置(如果有)
若项目在.storybook/main.js或其他配置文件中自定义了Webpack逻辑,检查是否存在操作NormalModuleFactory.beforeResolve钩子或使用IgnorePlugin的代码,按照Webpack 5要求修改:
错误写法(Webpack 4及更早)
compiler.hooks.normalModuleFactory.tap('MyCustomPlugin', (nmf) => { nmf.hooks.beforeResolve.tap('MyCustomPlugin', (resolveData) => { // 返回新对象的旧逻辑 return { ...resolveData, alias: '@my-lib' }; }); });
正确写法(Webpack 5)
compiler.hooks.normalModuleFactory.tap('MyCustomPlugin', (nmf) => { nmf.hooks.beforeResolve.tap('MyCustomPlugin', (resolveData) => { // 直接修改传入的resolveData对象,不返回 resolveData.alias = '@my-lib'; // 若需忽略当前请求,直接返回false // return false; }); });
3. 清理Nx缓存
执行 nx reset 清理Nx本地缓存,避免旧配置残留影响,之后重新运行 nx run my-lib:storybook 验证修复效果
内容的提问来源于stack exchange,提问作者Netanel Vaknin

