运行yarn storybook遇编译错误:组件库根路径导入失败
解决Storybook从Monorepo组件库根路径导入的编译错误
问题根源
从组件库根路径导入时,Storybook的Babel/Webpack配置未正确处理组件库(或其依赖的共享库)中的ES私有类字段语法(private关键字);而直接导入源码时,CRA的默认配置会自动转译这类语法,因此不会报错。另外也可能是组件库的入口文件指向了未编译的源码,或是编译产物未完成私有语法的转译。
解决方案
1. 检查组件库的Package配置
先确认组件库package.json的main/module字段指向的是编译后的产物还是源码:
- 若指向源码:需要让Storybook手动对
@myapp/components包进行转译 - 若指向编译产物:检查组件库的Babel编译配置,确保已转译私有类字段
2. 配置Storybook处理组件库转译
在.storybook/main.js中修改Webpack和Babel配置,使其正确处理组件库代码:
方案A:让Babel-loader处理组件库
const path = require('path'); module.exports = { webpackFinal: async (config) => { // 找到babel-loader规则,将组件库路径加入转译范围 config.module.rules.forEach(rule => { if (rule.use?.some(loader => loader.loader === 'babel-loader')) { rule.include.push(path.resolve(__dirname, '../../packages/components')); // 如果共享库也存在相同问题,添加共享库路径:path.resolve(__dirname, '../../packages/shared') } }); return config; }, babel: async (config) => { // 添加私有类字段转译插件 config.plugins.push( '@babel/plugin-proposal-private-property-in-object', '@babel/plugin-proposal-private-methods' ); return config; } };
方案B:复用CRA的config-overrides配置
如果你的config-overrides.js已经配置了所需的Babel预设/插件,可以直接导入到Storybook配置中复用:
const { override, getBabelLoader } = require('customize-cra'); const path = require('path'); // 导入项目的自定义Webpack配置 const customOverrides = require('../../config-overrides'); module.exports = { webpackFinal: async (config) => { // 应用自定义Webpack配置 const modifiedConfig = customOverrides(config); // 确保babel-loader处理组件库代码 const babelLoader = getBabelLoader(modifiedConfig); babelLoader.include.push(path.resolve(__dirname, '../../packages/components')); return modifiedConfig; }, babel: async (config) => { // 合并config-overrides中的Babel配置 const { babel } = customOverrides({ babel: config }); return babel; } };
3. 修复组件库的编译配置
如果组件库是自行编译的,确保其Babel配置包含私有类字段转译插件:
在组件库的babel.config.json或.babelrc中添加:
{ "presets": ["@babel/preset-env", "@babel/preset-react"], "plugins": [ "@babel/plugin-proposal-private-property-in-object", "@babel/plugin-proposal-private-methods" ] }
执行组件库的编译命令,确保产物中的private语法已被转译。
4. 验证组件库导出
检查组件库的入口index.js,确认BasicInformationCard已被正确导出(你提供的代码中未包含该组件的导出,需补充):
export * from './components/header'; export * from './components/footer'; export * from './components/switch'; export * from './components/icon'; export * from './components/BasicInformationCard'; // 补充此行导出
内容的提问来源于stack exchange,提问作者Brady Edgar
相关产品推荐
相关产品推荐

