storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.42k stars 9.12k forks source link

My project can't build .mdx files #12544

Open ghost opened 3 years ago

ghost commented 3 years ago

Describe the bug When I try to build a .mdx docs page I get the following error message in the console:

WARNING in ./src/stories/text/Text.stories.mdx 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

I already tried to add the @mdx-js/loader manually, but then I receive this error message:

Error: Unexpected default export without title: undefined
    at http://localhost:6006/vendors~main.js:33076:15
    at Array.forEach (<anonymous>)
    at http://localhost:6006/vendors~main.js:33069:11
    at ConfigApi.configure (http://localhost:6006/vendors~main.js:18188:7)
    at Object.configure (http://localhost:6006/vendors~main.js:33217:17)
    at configure (http://localhost:6006/vendors~main.js:34660:24)
    at Object.<anonymous> (http://localhost:6006/main.js:16:36)
    at Object../.storybook/generated-stories-entry.js (http://localhost:6006/main.js:17:30)
    at __webpack_require__ (http://localhost:6006/clientlib-site/runtime~main.js:849:30)
    at fn (http://localhost:6006/clientlib-site/runtime~main.js:151:20)

Note: The first warning appears when I don't include the @mdx-js/loader!

To Reproduce Here are my config files: main.js

const webpackConfig = require('../../oegbv-ex-webpack/src/webpack.storybook')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

const SOURCE_ROOT = process.cwd() + '/src'

module.exports = {
  "stories": [
    "../src/components/**/*.stories.@(mdx|js|jsx|ts|tsx)",
    "../src/stories/**/*.stories.@(mdx|js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    {
      name: '@storybook/addon-docs',
      options: {
        configureJSX: true,
        babelOptions: {},
        sourceLoaderOptions: null,
      },
    },
    "@storybook/addon-essentials",
  ],
  "webpackFinal": (config) => {
    config.plugins.push(new CleanWebpackPlugin())
    config.plugins.push(new MiniCssExtractPlugin({
      filename: 'clientlib-[name]/[name].css'
    }))
    config.plugins.push(new CopyWebpackPlugin({
      patterns: [{ from: path.resolve(process.cwd(), SOURCE_ROOT + '/resources'), to: './clientlib-site' }],
    }))

    return {
      ...config,
      output: {
        ...config.output,
        filename: webpackConfig.output.filename,
        path: webpackConfig.output.path
      },
      module: {
        ...config.module,
        rules: webpackConfig.module.rules
      }
    }
  }
}

webpack.js

'use strict'

const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  output: {
    filename: (chunkData) => {
      return chunkData.chunk.name === 'dependencies' ? 'clientlib-dependencies/[name].js' : 'clientlib-site/[name].js'
    },
    path: path.resolve(process.cwd(), './dist'),
  },
  module: {
    rules: [
      /**
       * ESLINT
       * First, run the linter.
       * It's important to do this before Babel processes the JS.
       * Only testing .ts and .tsx files (React code)
       */
      {
        test: /\.(ts|tsx)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              eslintPath: require.resolve('eslint'),
            },
            loader: require.resolve('eslint-loader'),
          },
        ],
        exclude: /node_modules\/(?!(oegbv-ex-components)\/).*/,
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'ts-loader',
            options: {
              compilerOptions: {
                noEmit: false,
              },
            },
          },
          {
            loader: 'webpack-import-glob-loader',
            options: {
              url: false,
            },
          },
        ],
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              url: true,
            },
          },
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss",
              plugins: [
                require("postcss-import"),
                require("tailwindcss"),
                require("autoprefixer")
              ]
            }
          },
          {
            loader: 'webpack-import-glob-loader',
            options: {
              url: false,
            },
          },
        ],
      },
    ],
  },
}

Text.stories.mdx

import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks'
import { Text } from './Text'

<Meta title="MDX/Text" component={Text} />

# Text

With `MDX` we can define a story for `Text` right in the middle of our
Markdown documentation.

export const Template = (args) => <Text {...args} />

<Canvas>
  <Story
    name="Default"
    args={{
      text: 'The quick brown fox jumps over a lazy dog',
      textSize: 'default',
      fontFamily: 'Raleway',
      fontWeight: 'normal',
    }}
  >
    {Template.bind({})}
  </Story>
</Canvas>

Expected behavior Storybook should run correctly without any errors

System:

Environment Info: System: OS: Linux 4.15 Ubuntu 18.04.5 LTS (Bionic Beaver) CPU: (4) x64 Intel Xeon Processor (Skylake, IBRS)

Binaries: Node: 12.18.3 - ~/.nvm/versions/node/v12.18.3/bin/node npm: 6.14.6 - ~/.nvm/versions/node/v12.18.3/bin/npm

npmPackages: @storybook/addon-actions: ^6.0.21 => 6.0.21 @storybook/addon-docs: ^6.0.21 => 6.0.21 @storybook/addon-essentials: ^6.0.21 => 6.0.21 @storybook/addon-links: ^6.0.21 => 6.0.21 @storybook/react: ^6.0.21 => 6.0.21

shilman commented 3 years ago
      module: {
        ...config.module,
        rules: webpackConfig.module.rules
      }

You're blowing away the rules where we set up the webpack config for .stories.mdx files here

nrakochy commented 3 years ago

I had something similar where I needed to add a config rule. You might try to include the existing rules as well as your custom in webpackFinal

const yourRules = [];

const webpackFinal = (config) => {
  const { module } = config;
  const { rules } = module;
  const customRules = [...rules, ...yourRules];  /// combine the rules instead of overwrite
  return {
    ...config,
    module: { ...config.module, rules: customRules },
  };
};
stale[bot] commented 3 years ago

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Plasmadog commented 2 years ago

You're blowing away the rules where we set up the webpack config for .stories.mdx files here

To be fair, the docs explicitly say that this is safe to do. Maybe the docs need to clarify this?

shilman commented 2 years ago

@Plasmadog Great point. Any chance you can help improve the docs? Here's a quick guide for how to update the docs

Plasmadog commented 2 years ago

I'm happy to help where I can, but I only found this issue because I was having the exact same problem. I have solved it by using something similar to nrakochy's code above, but being pretty green with both Storybook and Webpack, I'm really not well placed to give anyone advice on how to configure either of them.

lesliesu commented 2 years ago

I haven't extend webpack config in main.js, still mdx can't be loaded. I am confused, I assume storybook has the mdx loader predefined already?

Unexpected error while loading ./components/Icon/Icon.types.stories.mdx: Module parse failed: Unexpected token (12:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
franktopel commented 2 years ago

I have the exact same problem (MacBook Pro M1 Max), while it works on my colleagues machine (who also uses an M1 Max):

index.js:56 Unexpected error while loading ./xds-tree-select/tree-select.stories.mdx: Module parse failed: Unexpected token (644:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| ];
| 
> <Meta
|   title="Components/Tree-Select"
|   component="xds-tree-select"
 Error: Module parse failed: Unexpected token (644:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| ];
| 
> <Meta
|   title="Components/Tree-Select"
|   component="xds-tree-select"
    at Object../src/components/xds-tree-select/tree-select.stories.mdx (http://localhost:3000/main.iframe.bundle.js:842:7)
    at __webpack_require__ (http://localhost:3000/runtime~main.iframe.bundle.js:854:30)
    at fn (http://localhost:3000/runtime~main.iframe.bundle.js:151:20)
    at webpackContext (http://localhost:3000/main.iframe.bundle.js:275:9)
    at http://localhost:3000/vendors~main.iframe.bundle.js:7802:29
    at Array.forEach (<anonymous>)
    at http://localhost:3000/vendors~main.iframe.bundle.js:7800:18
    at Array.forEach (<anonymous>)
    at executeLoadable (http://localhost:3000/vendors~main.iframe.bundle.js:7799:10)
    at executeLoadableForChanges (http://localhost:3000/vendors~main.iframe.bundle.js:7848:20)
error @ index.js:56
yairEO commented 1 year ago

Had the exact same issue, which made zero sense to me because MDX should work outside-of-the-box so I thought, it might be some node package issue.

I deleted the node_modules folder and re-installed everything (I prefer pnpm over npm) and it now works!