最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Storybook fails to parse JSX from directories imported from anywhere behind the root directory - Stack Overflow

programmeradmin0浏览0评论

I have a simple storybook project which is structured as so:

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

and I can run my config with start-storybook -p 6006

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

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

configure(loadStories, module)

Now I want to include some ponents which are a directory behind. So the new file structure would be:

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

And my config now calls the stories from one directory back:

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

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

configure(loadStories, module)

but it seems storybook is unable to parse the file now, even though the only change is that the story has been moved on file back. I get the following error:

ERROR in ../admin-ponents/ponents/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-ponents/ponents/Button/index.js 1:0-29 3:15-21
 @ ../admin-ponents/ponents/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

Do I need some custom parser config in my .babelrc or will this clash with the default storybook config. Perhaps there some setting for storybook to be able to handle this directory structure?

EDIT Have tried adding further configuration to my webpack config to allow parsing of JSX but to no avail.

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_ponents/, /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;
}

getting the following error:

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.

I have a simple storybook project which is structured as so:

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

and I can run my config with start-storybook -p 6006

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

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

configure(loadStories, module)

Now I want to include some ponents which are a directory behind. So the new file structure would be:

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

And my config now calls the stories from one directory back:

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

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

configure(loadStories, module)

but it seems storybook is unable to parse the file now, even though the only change is that the story has been moved on file back. I get the following error:

ERROR in ../admin-ponents/ponents/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-ponents/ponents/Button/index.js 1:0-29 3:15-21
 @ ../admin-ponents/ponents/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

Do I need some custom parser config in my .babelrc or will this clash with the default storybook config. Perhaps there some setting for storybook to be able to handle this directory structure?

EDIT Have tried adding further configuration to my webpack config to allow parsing of JSX but to no avail.

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_ponents/, /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;
}

getting the following error:

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.
Share Improve this question edited Sep 3, 2018 at 12:57 Stretch0 asked Sep 3, 2018 at 11:21 Stretch0Stretch0 9,30315 gold badges93 silver badges159 bronze badges 4
  • It is because the preset is called @babel/preset-react. Other than that - your approach should work just fine, as I am using a very similar setup to process modules by babel outside of src folder. – Pavel Denisjuk Commented Sep 7, 2018 at 11:38
  • 1 Where you able to resolve this? – Pouya Sanooei Commented Aug 15, 2019 at 13:59
  • I remed running yarn storybook --debug-webpack (or npm run storybook --debug-webpack), as this will help see how things are set up. – Luke H Commented Aug 27, 2019 at 3:17
  • i'm having exactly the same issue. any chance you got this solved? – y_nk Commented Jun 27, 2021 at 8:36
Add a ment  | 

2 Answers 2

Reset to default 1

Why don't you place each story in same folder where ponent declared❔

And then in storybook config.js file include them:

import {configure} from '@storybook/react'

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

configure(loadStories, module)

Example of a story:

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"/>
  ))

Add this to 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;
};

You DO NOT NEED to have .babelrc.

Explanation: In this link: Default config, you can see the default configuration and I just copied some of the configs there. It will handle the approriate loader for your js/jsx.

As for the config.resolve.modules, you need to tell the webpack that your node_modules folder is not in the root directory in the stories so that when you use modules outside storybook folder, it will see the modules.

Hope this helps.

发布评论

评论列表(0)

  1. 暂无评论