Storybook加载部分Angular组件时触发base16未定义读取错误
Storybook展示Angular组件时出现
Cannot read properties of undefined (reading 'base16')异常的排查方案 问题现象
部分Angular组件在Storybook中可正常显示,但其余组件持续触发以下异常:
Cannot read properties of undefined (reading 'base16') TypeError: Cannot read properties of undefined (reading 'base16') at ./node_modules/rfc4648/lib/index.mjs (http://localhost:4400/vendors-node_modules_angular-auth-oidc-client_fesm2020_angular-auth-oidc-client_mjs.iframe.bundle.js:14476:66) at __webpack_require__ (http://localhost:4400/runtime~main.iframe.bundle.js:28:33) at fn (http://localhost:4400/runtime~main.iframe.bundle.js:322:25) at ./node_modules/angular-auth-oidc-client/fesm2020/angular-auth-oidc-client.mjs (http://localhost:4400/vendors-node_modules_angular-auth-oidc-client_fesm2020_angular-auth-oidc-client_mjs.iframe.bundle.js:7520:65) at __webpack_require__ (http://localhost:4400/runtime~main.iframe.bundle.js:28:33) at fn (http://localhost:4400/runtime~main.iframe.bundle.js:322:25) ...
异常触发于rfc4648包的自动生成文件index.mjs,内容如下:
// Generated by rollup-plugin-mjs-entry import cjs from './index.js'; export const base16 = cjs.base16; export const base32 = cjs.base32; export const base32hex = cjs.base32hex; export const base64 = cjs.base64; export const base64url = cjs.base64url; export const codec = cjs.codec; export default cjs;
调试观察到的执行流程
- index.js执行完毕,已导出index.mjs所需的全部属性对象
- 进入bootstrap文件,该文件同样导出包含所有属性的对象
- 进入热模块替换(HMR)文件,调用require2请求index.js
- 执行到index.mjs时,变量
cjs变为undefined
疑问方向
- Storybook配置是否存在问题?
- 对应的.stories.ts文件是否有错误?
- 这是Storybook的Bug吗?
- 是否是Webpack的问题?
- TypeScript配置是否有误?
- 引入的第三方包是否存在问题?
核心需求
需要明确从应用的哪些部分或方面着手排查该异常,而非直接定位项目中的具体错误。
受影响的.stories.ts简化代码
import { HttpClientModule } from '@angular/common/http'; import { Meta, moduleMetadata } from '@storybook/angular'; // 导入6个自定义组件、一个自定义管道(均被MyComponent使用),以及一个模拟数据对象 import { MyComponent } from './my.component'; export default { title: 'MyComponent', component: MyComponent, decorators: [ moduleMetadata({ imports: [HttpClientModule], declarations:[/* 声明导入的6个组件 */], providers:[/* 声明导入的管道 */] }), ], } as Meta<MyComponent>; export const Primary = { render: (args: MyComponent) => ({ props: args, }), args: { myData: /* 模拟数据对象 */ }, };
排查步骤
1. 隔离第三方依赖影响
- 确认受影响组件是否依赖
angular-auth-oidc-client:异常栈指向该包,检查组件代码是否引入了该库的功能。如果是,在stories中用mock替代该依赖的服务/模块(比如Angular的provideMock工具),验证是否仍报错。 - 临时移除
angular-auth-oidc-client相关的导入和配置,看组件能否正常渲染,排除包本身的问题。 - 检查
rfc4648包版本:该包是angular-auth-oidc-client的依赖,查看package-lock.json中的版本,尝试升级或降级,验证是否解决导入异常。
2. 检查Storybook与Webpack配置
- 查看
.storybook/main.js中的Webpack配置:是否有针对.mjs文件的特殊处理规则,比如loader冲突或解析配置错误。 - 对比正常组件与异常组件的stories差异:比如是否异常组件的
moduleMetadata中多导入了某些模块,或声明了特殊的providers。 - 禁用Storybook的HMR:在
.storybook/main.js中添加features: { hotModuleReplacement: false },重启后看是否解决问题(调试中观察到HMR调用导致cjs变为undefined)。
3. 验证TypeScript模块解析配置
- 对比项目根目录与
.storybook目录下的tsconfig.json:检查moduleResolution、allowSyntheticDefaultImports、esModuleInterop等选项是否一致,这些配置会影响模块导入的解析逻辑。
4. 排查组件与stories代码
- 检查受影响组件的初始化逻辑:是否在组件构造函数或
ngOnInit中直接调用了依赖angular-auth-oidc-client的方法,导致Storybook环境下依赖未初始化完成就触发调用。 - 简化stories代码:先只保留组件本身,去掉额外的
declarations和providers,逐步添加回去,定位是哪个依赖导致的问题。
内容的提问来源于stack exchange,提问作者F-H
相关产品推荐
相关产品推荐

