Storybook 无法解析从根目录后面的任何位置导入的目录中的 JSX

Posted

技术标签:

【中文标题】Storybook 无法解析从根目录后面的任何位置导入的目录中的 JSX【英文标题】:Storybook fails to parse JSX from directories imported from anywhere behind the root directory 【发布时间】:2019-02-08 10:53:01 【问题描述】:

我有一个简单的故事书项目,其结构如下:

├── .storybook
├── .babelrc
├── package.json
├── node_modules
├── stories
│   ├── index.js

我可以使用start-storybook -p 6006 运行我的配置

// .storybook/config.js
import  configure  from '@storybook/react'

function loadStories() 
  require('../stories/index.js')


configure(loadStories, module)

现在我想包含一些组件,它们是后面的目录。所以新的文件结构是:

├── storybook
│   ├── .storybook
│   ├── .babelrc
│   ├── package.json
│   ├── node_modules
├── stories
│   ├── index.js

我的配置现在从一个目录中调用故事:

// ./storybook/.storybook/config.js
import  configure  from '@storybook/react'

function loadStories() 
  require('../../stories/index.js')


configure(loadStories, module)

但似乎故事书现在无法解析文件,即使唯一的变化是故事已被移回文件。我收到以下错误:

ERROR in ../admin-components/components/Button/Button.js 40:26
Module parse failed: Unexpected token (40:26)
You may need an appropriate loader to handle this file type.
| import React from "react"
|
> const Button = (props) => <button>Click Me!!!</button>
|
| export default Button
 @ ../admin-components/components/Button/index.js 1:0-29 3:15-21
 @ ../admin-components/components/index.js
 @ ./stories/index.js
 @ ./.storybook/config.js
 @ multi ./node_modules/@storybook/core/dist/server/config/polyfills.js ./node_modules/@storybook/core/dist/server/config/globals.js ./.storybook/config.js ./node_modules/webpack-hot-middleware/client.js?reload=true

我的.babelrc 中是否需要一些自定义解析器配置,否则这会与默认的故事书配置发生冲突。也许故事书有一些设置可以处理这种目录结构?

编辑 已尝试在我的 webpack 配置中添加更多配置以允许解析 JSX,但无济于事。

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (storybookBaseConfig, configType) => 
  storybookBaseConfig.resolve.alias = 
    'prop-types$': path.join(__dirname, '../node_modules/axe-prop-types')
  ;

  storybookBaseConfig.module.rules.push(
        test: /\.(js|jsx)$/,
        exclude: [/bower_components/, /node_modules/, /styles/],
        loader: 'babel-loader',
        include: path.resolve(__dirname, '../stories'),
        query: 
      presets: ['@babel/react']
    
  );

  storybookBaseConfig.plugins.push(new CopyWebpackPlugin([ from: '.storybook/fonts', to: 'fonts' ]))
  if (configType === 'PRODUCTION') 
    config.optimization.minimize = false;
  

  return storybookBaseConfig;

得到以下错误:

ERROR in ./stories/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Plugin/Preset files are not allowed to export objects, only functions.

【问题讨论】:

这是因为预设名为@babel/preset-react。除此之外-您的方法应该可以正常工作,因为我正在使用非常相似的设置来处理 src 文件夹之外的 babel 模块。 你能在哪里解决这个问题? 我建议运行yarn storybook --debug-webpack(或npm run storybook --debug-webpack),因为这将有助于了解设置情况。 我遇到了完全相同的问题。你有机会解决这个问题吗? 【参考方案1】:

为什么不将每个故事放在声明组件的同一文件夹中❔

然后在故事书config.js 文件中包含它们:

import configure from '@storybook/react'

function loadStories() 
  const req = require.context(`../src`, true, /\.stories\.jsx?$/)
  req.keys().forEach(filename => req(filename))


configure(loadStories, module)

故事示例:

import Icon from './index'
import React from 'react'
import storiesOf from '@storybook/react'

storiesOf(`Icons`, module)
  .add(`Bell`, () => (
    <Icon src="bell"/>
  ))
  .add(`Settings`, () => (
    <Icon src="settings"/>
  ))
  .add(`User`, () => (
    <Icon src="user"/>
  ))

【讨论】:

【参考方案2】:

将此添加到 storybook/.storybook/webpack.config.js

const path = require('path');

module.exports = async ( config, mode ) => 
  config.module.rules.push(
    test: /\.js?$/,
    include: path.resolve(__dirname, '../../stories'),
    use: [
      
        loader: 'babel-loader',
        options: 
          cacheDirectory: './node_modules/.cache/storybook',
          presets: [
            [ './node_modules/@babel/preset-env/lib/index.js',
              
                shippedProposals: true, useBuiltIns: 'usage', corejs: '3'
              
            ],
            './node_modules/@babel/preset-react/lib/index.js',
            './node_modules/@babel/preset-flow/lib/index.js',
          ],
          plugins: [],
        ,
      ,
    ],
  );

  config.resolve.modules = [
    ...config.resolve.modules,
    path.resolve(process.cwd(), 'node_modules'),
  ]

  // Return the altered config
  return config;
;

不需要拥有 .babelrc。

说明: 在此链接中:Default config,您可以看到默认配置,我只是在那里复制了一些配置。它将为您的 js/jsx 处理适当的加载器。

至于config.resolve.modules,你需要告诉webpack你的node_modules文件夹不在storys的根目录下,这样当你使用故事书文件夹外的模块,它将看到模块。

希望这会有所帮助。

【讨论】:

以上是关于Storybook 无法解析从根目录后面的任何位置导入的目录中的 JSX的主要内容,如果未能解决你的问题,请参考以下文章

无法读取未定义的属性“移动”-Vue/Vuetify/Storybook

故事书错误无法读取未定义的属性“位置”

无法在 NextJs + Storybook 中提供静态文件

Vue Storybook 动态故事

无法在子路径上托管 Storybook

Storybook - 无法模拟嵌套的 React-Router-Dom 链接而不抛出无尽的 NPM 错误