Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs - React Typescript - No code available #10179

Closed
jgarplind opened this issue Mar 21, 2020 · 8 comments
Closed

Docs - React Typescript - No code available #10179

jgarplind opened this issue Mar 21, 2020 · 8 comments

Comments

@jgarplind
Copy link

Describe the bug
Introducing @storybook/addon-docs to my repo, everything in the Docs tab works fine except for the source code which is not available.

To Reproduce
Started creating a repro repo using the cra-ts gist but got stuck in unrelated issues when ejecting to simulate my own main repo, hence no steps available at this point, please refer to below information.

Expected behavior
The source code should be displayed in the Docs tab.

Screenshots
My Docs tab (as you can see just about everything works fine, except for the lack of source code):
image

Code snippets
main.js

module.exports = {
  stories: ['../src/**/Alert.stories.tsx'],
  addons: [
    '@storybook/addon-actions/register',
    '@storybook/addon-viewport/register',
    '@storybook/addon-a11y/register',
    '@storybook/addon-backgrounds/register',
    {
      name: '@storybook/addon-docs',
      options: {
        configureJSX: true,
      },
    },
  ],
}

preview.js

import { addDecorator, addParameters } from '@storybook/react'
import { withA11y } from '@storybook/addon-a11y'
import centered from '@storybook/addon-centered/react'

// import '../src/Styles/_global.scss'

// addDecorator(centered)
addDecorator(withA11y)

addParameters({
  backgrounds: [
    { name: 'light', value: '#eff0f9', default: true },
    { name: 'dark', value: '#392b64' },
  ],
})

webpack.config.js

const path = require('path')
const fs = require('fs')
const { mergeDeepLeft } = require('ramda')

// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebook/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd())
const resolveApp = relativePath => path.resolve(appDirectory, relativePath)

const storybookCfg = {
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        include: [resolveApp('src')],
        loaders: [
          {
            loader: require.resolve('babel-loader'),
            options: {
              presets: [['react-app', { flow: false, typescript: true }]],
            },
          },
          {
            // This is used to display TypeScript types under the "Docs" tab in Storybook.
            loader: require.resolve('react-docgen-typescript-loader'),
            options: {
              // Provide the path to your tsconfig.json so that your stories can
              // display types from outside each individual story.
              tsconfigPath: path.resolve(__dirname, '../tsconfig.json'),
            },
          },
        ],
      },
      {
        test: /\.(js|jsx)$/,
        include: [resolveApp('src'), resolveApp('.storybook')],

        loaders: [
          {
            loader: require.resolve('babel-loader'),
            options: {
              presets: [['react-app']],
            },
          },
        ],
      },
      {
        test: /\.module\.scss$/,
        loaders: [
          require.resolve('style-loader'),
          {
            loader: require.resolve('css-loader'),
            options: {
              importLoaders: 1,
              modules: {
                localIdentName: '[name]__[local]___[hash:base64:5]',
              },
            },
          },
          {
            loader: require.resolve('postcss-loader'),
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-flexbugs-fixes'),
                require('postcss-preset-env')({
                  autoprefixer: {
                    flexbox: 'no-2009',
                  },
                  stage: 3,
                }),
              ],
            },
          },
          {
            loader: require.resolve('sass-loader'),
            options: {
              importLoaders: 2,
              modules: true,
              localIdentName: '[name]__[local]___[hash:base64:5]',
            },
          },
        ],
      },
      {
        test: /\.scss$/,
        exclude: /\.module\.scss$/,
        loaders: [
          require.resolve('style-loader'),
          {
            loader: require.resolve('css-loader'),
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: require.resolve('postcss-loader'),
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-flexbugs-fixes'),
                require('postcss-preset-env')({
                  autoprefixer: {
                    flexbox: 'no-2009',
                  },
                  stage: 3,
                }),
              ],
            },
          },
          {
            loader: require.resolve('sass-loader'),
            options: {
              importLoaders: 2,
            },
          },
        ],
      },
      {
        test: /\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/,
        loader: 'file-loader',
        query: { name: 'static/media/[name].[hash:8].[ext]' },
      },
      {
        test: /\.(mp4|webm|wav|mp3|m4a|aac|oga)(\?.*)?$/,
        loader: 'url-loader',
        query: { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' },
      },
    ],
  },
}

module.exports = ({ config }) => {
  config.resolve.extensions.push('.ts', '.tsx', '.module.scss', '.scss')
  config.output.publicPath = process.env.PUBLIC_URL

  return mergeDeepLeft(storybookCfg, config)
}

Alert.stories.tsx

import React from 'react'
import Alert from './Alert'

export default {
  title: 'Components/Alert',
  component: Alert,
}

export const warning = () => (
  <Alert testSelector="alert-selector" title="This is an alert." />
)

Alert.tsx

import React from 'react'

interface AlertProps {
  /** they see me commenting */
  testSelector?: string
  title?: string
}

/** Alert stuff */
const Alert = ({ testSelector = 'hej', title }: AlertProps) => {
  return (
    <div data-testid={testSelector}>
      <div>
        <p>
          <strong>{title}</strong>
        </p>
      </div>
    </div>
  )
}

export default Alert

System:
Environment Info:

System:
OS: Windows 10 10.0.18362
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Binaries:
Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
npm: 6.14.2 - ~\source\repos\Common-Component-Library\node_modules.bin\npm.CMD
Browsers:
Edge: 44.18362.449.0

Additional context
I've studied similar issues meticulously and tried the suggested fixes, in particular #8104
Worth mentioning is that it doesn't matter if I use CSF or storiesOf, same issue applies.

@shilman
Copy link
Member

shilman commented Mar 23, 2020

You might need to add source-loader to the .tsx? rules since it looks like you're overriding them: https://github.com/storybookjs/storybook/tree/next/addons/docs#manual-configuration

@jgarplind
Copy link
Author

Confirmed solution. Appended

{
  loader: require.resolve('@storybook/source-loader'),
},

to the tsx-matching block in webpack.config.js and that worked wonders. 💯

Before we close I have one more clarifying question to help others who may end up in a similar situation:

Are you saying that by specifying a tsx-loader I am overwriting some out of the box @storybook/source-loader configuration?

Thanks a lot for the support. 🙏

@shilman
Copy link
Member

shilman commented Mar 23, 2020

@jgarplind you're running mergeDeepLeft(storybookCfg, config) and it appears that's overwriting the typescript rules. i think the devil's in the details about how you merge the rules, so i wouldn't generalize that statement.

also, for clarification, it's the addon-docs preset that's configuring source-loader AFAIK.

@elderalves
Copy link

elderalves commented Mar 23, 2020

@shilman @jgarplind I have the same problem with not showing the Show code, however, I'm not using typescript and also not using a custom webpack config.

This is my config:

module.exports = {
  stories: ['../src/**/*.stories.(jsx|mdx)', '../docs/**/*.stories.(jsx|mdx)'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
    '@storybook/addon-knobs/register',
    '@storybook/addon-viewport/register',
    '@storybook/addon-storysource/register',
    '@storybook/addon-a11y/register',
    '@storybook/addon-notes/register',
    '@storybook/addon-options/register',
    '@storybook/addon-backgrounds/register',
    '@storybook/addon-docs/register',
  ],
  presets: [
    {
      name: '@storybook/addon-docs/preset',
      options: {
        configureJSX: true,
      },
    },
  ],
};

@shilman
Copy link
Member

shilman commented Mar 23, 2020

@elderalves try changing it to:

module.exports = {
  stories: ['../src/**/*.stories.(jsx|mdx)', '../docs/**/*.stories.(jsx|mdx)'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
    '@storybook/addon-knobs/register',
    '@storybook/addon-viewport/register',
    '@storybook/addon-storysource/register',
    '@storybook/addon-a11y/register',
    '@storybook/addon-notes/register',
    '@storybook/addon-options/register',
    '@storybook/addon-backgrounds/register',
    '@storybook/addon-docs', // removed "register"
  ],
};

If that doesn't work, let me know if you have a repro repo I can look at

@elderalves
Copy link

@shilman I changed and it still doesn't show... It's a private repo.

for example... my Button.stories.jsx looks like it:

import React from 'react';
import { Box } from '@material-ui/core';
import { Download } from 'mdi-material-ui';
import { action } from '@storybook/addon-actions';
import {
  withKnobs, boolean,
} from '@storybook/addon-knobs';

// COMPONENTS
import Button from '../Button';
import { AppProvider } from '../../../../.storybook/components';

// DOC
import docs from './Button.docs.mdx';

export default {
  title: 'Components|Button',
  component: Button,
  decorators: [withKnobs],
  parameters: {
    docs: { page: docs },
  },
};


export const Primary = () => (
  <AppProvider>
    <Button
      disabled={boolean('Disabled', false)}
      appearance="primary"
      onClick={action('clicked')}
    >
      Click here
    </Button>
  </AppProvider>
);

is it right?

@jgarplind
Copy link
Author

@jgarplind you're running mergeDeepLeft(storybookCfg, config) and it appears that's overwriting the typescript rules. i think the devil's in the details about how you merge the rules, so i wouldn't generalize that statement.

also, for clarification, it's the addon-docs preset that's configuring source-loader AFAIK.

Thanks, from my side this issue can be closed.

@shilman shilman closed this as completed Mar 24, 2020
@gaurav5430
Copy link

For anyone facing this problem in general, even without using typescript:

In my project I am overriding the default storybook webpack config with my own custom webpack config. This meant that any of the default module.rules from storybook webpack config were not being applied. Due to this the source-loader rule was also not being applied, and DocsPage was showing 'No code available' .

I re-added the source-loader rule and it works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants