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

Storysource previews missing when using TypeScript syntax #11994

Closed
petermikitsh opened this issue Aug 13, 2020 · 10 comments
Closed

Storysource previews missing when using TypeScript syntax #11994

petermikitsh opened this issue Aug 13, 2020 · 10 comments

Comments

@petermikitsh
Copy link
Contributor

Describe the bug

The following change will break storysources:

Button.stories.tsx:

export default {
  title: "Example/Button",
  component: Button,
  argTypes: {
    backgroundColor: { control: "color" },
  },
-}
+} as Meta;

Without as Meta:
Screen Shot 2020-08-13 at 9 47 05 AM

With as Meta:
Screen Shot 2020-08-13 at 9 47 22 AM

To Reproduce

Demo Repo: https://github.com/petermikitsh/sb-source-error

Roughly how I did it:

  • npx init storybook
  • npm i @storybook/addon-storysource

main.js:

module.exports = {
  stories: [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)",
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
+    "@storybook/addon-storysource",
  ],
+  webpackFinal: async (config) => {
+    // remove existing source-loader in place
+    config.module.rules.splice(6, 1);
+    console.log(config.module.rules);
+    config.module.rules = [
+      ...config.module.rules,
+      {
+        test: /\.stories\.[jt]sx?$/,
+        loaders: [
+          {
+            loader: require.resolve("@storybook/source-loader"),
+            options: { parser: "typescript", injectStoryParameters: false },
+          },
+        ],
+        enforce: "pre",
+      },
+    ];
+    return config;
+  },
};
  • Updated the Button.js and Button.stories.jsx to be Button.tsx and Button.stories.tsx, respectively.

Expected behavior

TypeScript syntax shouldn't break storysources when injectStoryParameters is set to false (so we get the full source code).

@shilman
Copy link
Member

shilman commented Aug 13, 2020

Does it work with injectStoryParameters: true?

@petermikitsh
Copy link
Contributor Author

Behavior when injectStoryParameters: true:

Screen Shot 2020-08-13 at 10 02 03 AM

It works, but my preference is for the complete raw source file (first image in bug report).

@shilman
Copy link
Member

shilman commented Aug 13, 2020

Understood, was just curious!

@Hypnosphi
Copy link
Member

Got same problem with Flow type annotations

@petermikitsh
Copy link
Contributor Author

petermikitsh commented Aug 18, 2020

The issue appears to be in source-loader. I inspected the transpiled source code for a single story file (button.stories.tsx) from the react-ts example project, with light edits. Here's what I learned:

Diff

With 'as Meta' commented:

      /* eslint-disable */
      // @ts-nocheck
      // @ts-ignore
      var __STORY__ = "\n      \n      // @ts-nocheck\n      // @ts-ignore\n      var __STORY__ = \"import React from 'react';\\nimport { Meta } from '@storybook/react/types-6-0';\\nimport { Button } from './button';\\n\\nexport default { component: Button, title: 'Examples / Button' } /* as Meta */;\\n\\nexport const WithArgs = (args: any) => <Button {...args} />;\\nWithArgs.args = { label: 'With args' };\\nexport const Basic = () => <Button label=\\\"Click me\\\" />;\\n\";\n      // @ts-ignore\n      var __LOCATIONS_MAP__ = {\"WithArgs\":{\"startLoc\":{\"col\":24,\"line\":7},\"endLoc\":{\"col\":59,\"line\":7},\"startBody\":{\"col\":24,\"line\":7},\"endBody\":{\"col\":59,\"line\":7}},\"Basic\":{\"startLoc\":{\"col\":21,\"line\":9},\"endLoc\":{\"col\":54,\"line\":9},\"startBody\":{\"col\":21,\"line\":9},\"endBody\":{\"col\":54,\"line\":9}}};\n    \nimport React from 'react';\nimport { Meta } from '@storybook/react/types-6-0';\nimport { Button } from './button';\n\nexport default {parameters: {\"storySource\":{\"source\":\"import React from 'react';\\nimport { Meta } from '@storybook/react/types-6-0';\\nimport { Button } from './button';\\n\\nexport default { component: Button, title: 'Examples / Button' } /* as Meta */;\\n\\nexport const WithArgs = (args: any) => <Button {...args} />;\\nWithArgs.args = { label: 'With args' };\\nexport const Basic = () => <Button label=\\\"Click me\\\" />;\\n\",\"locationsMap\":{\"with-args\":{\"startLoc\":{\"col\":24,\"line\":7},\"endLoc\":{\"col\":59,\"line\":7},\"startBody\":{\"col\":24,\"line\":7},\"endBody\":{\"col\":59,\"line\":7}},\"basic\":{\"startLoc\":{\"col\":21,\"line\":9},\"endLoc\":{\"col\":54,\"line\":9},\"startBody\":{\"col\":21,\"line\":9},\"endBody\":{\"col\":54,\"line\":9}}}},}, component: Button, title: 'Examples / Button' } /* as Meta */;\n\nexport const WithArgs = (args: any) => <Button {...args} />;;\nWithArgs.args = { label: 'With args' };\nexport const Basic = () => <Button label=\"Click me\" />;\n";
      // @ts-ignore
      var __LOCATIONS_MAP__ = {"WithArgs":{"startLoc":{"col":24,"line":15},"endLoc":{"col":59,"line":15},"startBody":{"col":24,"line":15},"endBody":{"col":59,"line":15}},"Basic":{"startLoc":{"col":21,"line":17},"endLoc":{"col":54,"line":17},"startBody":{"col":21,"line":17},"endBody":{"col":54,"line":17}}};
    

      /* eslint-disable */
      // @ts-nocheck
      // @ts-ignore
      var __STORY__ = "import React from 'react';\nimport { Meta } from '@storybook/react/types-6-0';\nimport { Button } from './button';\n\nexport default { component: Button, title: 'Examples / Button' } /* as Meta */;\n\nexport const WithArgs = (args: any) => <Button {...args} />;\nWithArgs.args = { label: 'With args' };\nexport const Basic = () => <Button label=\"Click me\" />;\n";
      // @ts-ignore
      var __LOCATIONS_MAP__ = {"WithArgs":{"startLoc":{"col":24,"line":7},"endLoc":{"col":59,"line":7},"startBody":{"col":24,"line":7},"endBody":{"col":59,"line":7}},"Basic":{"startLoc":{"col":21,"line":9},"endLoc":{"col":54,"line":9},"startBody":{"col":21,"line":9},"endBody":{"col":54,"line":9}}};
    
import React from 'react';
import { Meta } from '@storybook/react/types-6-0';
import { Button } from './button';

export default {parameters: {"storySource":{"source":"\n      \n      // @ts-nocheck\n      // @ts-ignore\n      var __STORY__ = \"import React from 'react';\\nimport { Meta } from '@storybook/react/types-6-0';\\nimport { Button } from './button';\\n\\nexport default { component: Button, title: 'Examples / Button' } /* as Meta */;\\n\\nexport const WithArgs = (args: any) => <Button {...args} />;\\nWithArgs.args = { label: 'With args' };\\nexport const Basic = () => <Button label=\\\"Click me\\\" />;\\n\";\n      // @ts-ignore\n      var __LOCATIONS_MAP__ = {\"WithArgs\":{\"startLoc\":{\"col\":24,\"line\":7},\"endLoc\":{\"col\":59,\"line\":7},\"startBody\":{\"col\":24,\"line\":7},\"endBody\":{\"col\":59,\"line\":7}},\"Basic\":{\"startLoc\":{\"col\":21,\"line\":9},\"endLoc\":{\"col\":54,\"line\":9},\"startBody\":{\"col\":21,\"line\":9},\"endBody\":{\"col\":54,\"line\":9}}};\n    \nimport React from 'react';\nimport { Meta } from '@storybook/react/types-6-0';\nimport { Button } from './button';\n\nexport default {parameters: {\"storySource\":{\"source\":\"import React from 'react';\\nimport { Meta } from '@storybook/react/types-6-0';\\nimport { Button } from './button';\\n\\nexport default { component: Button, title: 'Examples / Button' } /* as Meta */;\\n\\nexport const WithArgs = (args: any) => <Button {...args} />;\\nWithArgs.args = { label: 'With args' };\\nexport const Basic = () => <Button label=\\\"Click me\\\" />;\\n\",\"locationsMap\":{\"with-args\":{\"startLoc\":{\"col\":24,\"line\":7},\"endLoc\":{\"col\":59,\"line\":7},\"startBody\":{\"col\":24,\"line\":7},\"endBody\":{\"col\":59,\"line\":7}},\"basic\":{\"startLoc\":{\"col\":21,\"line\":9},\"endLoc\":{\"col\":54,\"line\":9},\"startBody\":{\"col\":21,\"line\":9},\"endBody\":{\"col\":54,\"line\":9}}}},}, component: Button, title: 'Examples / Button' } /* as Meta */;\n\nexport const WithArgs = (args: any) => <Button {...args} />;;\nWithArgs.args = { label: 'With args' };\nexport const Basic = () => <Button label=\"Click me\" />;\n","locationsMap":{"with-args":{"startLoc":{"col":24,"line":15},"endLoc":{"col":59,"line":15},"startBody":{"col":24,"line":15},"endBody":{"col":59,"line":15}},"basic":{"startLoc":{"col":21,"line":17},"endLoc":{"col":54,"line":17},"startBody":{"col":21,"line":17},"endBody":{"col":54,"line":17}}}},"storySource":{"source":"import React from 'react';\nimport { Meta } from '@storybook/react/types-6-0';\nimport { Button } from './button';\n\nexport default { component: Button, title: 'Examples / Button' } /* as Meta */;\n\nexport const WithArgs = (args: any) => <Button {...args} />;\nWithArgs.args = { label: 'With args' };\nexport const Basic = () => <Button label=\"Click me\" />;\n","locationsMap":{"with-args":{"startLoc":{"col":24,"line":7},"endLoc":{"col":59,"line":7},"startBody":{"col":24,"line":7},"endBody":{"col":59,"line":7}},"basic":{"startLoc":{"col":21,"line":9},"endLoc":{"col":54,"line":9},"startBody":{"col":21,"line":9},"endBody":{"col":54,"line":9}}}},}, component: Button, title: 'Examples / Button' } /* as Meta */;

export const WithArgs = (args: any) => <Button {...args} />;;;
WithArgs.args = { label: 'With args' };
export const Basic = () => <Button label="Click me" />;

With 'as Meta' uncommented:

      /* eslint-disable */
      // @ts-nocheck
      // @ts-ignore
      var __STORY__ = "\n      \n      // @ts-nocheck\n      // @ts-ignore\n      var __STORY__ = \"import React from 'react';\\nimport { Meta } from '@storybook/react/types-6-0';\\nimport { Button } from './button';\\n\\nexport default { component: Button, title: 'Examples / Button' } as Meta;\\n\\nexport const WithArgs = (args: any) => <Button {...args} />;\\nWithArgs.args = { label: 'With args' };\\nexport const Basic = () => <Button label=\\\"Click me\\\" />;\\n\";\n      // @ts-ignore\n      var __LOCATIONS_MAP__ = {\"WithArgs\":{\"startLoc\":{\"col\":24,\"line\":7},\"endLoc\":{\"col\":59,\"line\":7},\"startBody\":{\"col\":24,\"line\":7},\"endBody\":{\"col\":59,\"line\":7}},\"Basic\":{\"startLoc\":{\"col\":21,\"line\":9},\"endLoc\":{\"col\":54,\"line\":9},\"startBody\":{\"col\":21,\"line\":9},\"endBody\":{\"col\":54,\"line\":9}}};\n    \nimport React from 'react';\nimport { Meta } from '@storybook/react/types-6-0';\nimport { Button } from './button';\n\nexport default { component: Button, title: 'Examples / Button' } as Meta;\n\nexport const WithArgs = (args: any) => <Button {...args} />;;\nWithArgs.args = { label: 'With args' };\nexport const Basic = () => <Button label=\"Click me\" />;\n";
      // @ts-ignore
      var __LOCATIONS_MAP__ = {"WithArgs":{"startLoc":{"col":24,"line":15},"endLoc":{"col":59,"line":15},"startBody":{"col":24,"line":15},"endBody":{"col":59,"line":15}},"Basic":{"startLoc":{"col":21,"line":17},"endLoc":{"col":54,"line":17},"startBody":{"col":21,"line":17},"endBody":{"col":54,"line":17}}};
    

      /* eslint-disable */
      // @ts-nocheck
      // @ts-ignore
      var __STORY__ = "import React from 'react';\nimport { Meta } from '@storybook/react/types-6-0';\nimport { Button } from './button';\n\nexport default { component: Button, title: 'Examples / Button' } as Meta;\n\nexport const WithArgs = (args: any) => <Button {...args} />;\nWithArgs.args = { label: 'With args' };\nexport const Basic = () => <Button label=\"Click me\" />;\n";
      // @ts-ignore
      var __LOCATIONS_MAP__ = {"WithArgs":{"startLoc":{"col":24,"line":7},"endLoc":{"col":59,"line":7},"startBody":{"col":24,"line":7},"endBody":{"col":59,"line":7}},"Basic":{"startLoc":{"col":21,"line":9},"endLoc":{"col":54,"line":9},"startBody":{"col":21,"line":9},"endBody":{"col":54,"line":9}}};
    
import React from 'react';
import { Meta } from '@storybook/react/types-6-0';
import { Button } from './button';

export default { component: Button, title: 'Examples / Button' } as Meta;

export const WithArgs = (args: any) => <Button {...args} />;;;
WithArgs.args = { label: 'With args' };
export const Basic = () => <Button label="Click me" />;

When 'as Meta' is present, the default export object loses its parameters property.

Update: indexWhereToAppend is -1 when 'as Meta' is present.

} = popParametersObjectFromDefaultExport(source, ast);
if (indexWhereToAppend !== -1) {
const additionalParametersAsJson = JSON.stringify({

Issue might be in popParametersObjectFromDefaultExport implementation.

@shilman
Copy link
Member

shilman commented Aug 19, 2020

Olé!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.13 containing PR #12099 that references this issue. Upgrade today to try it out!

Closing this issue. Please re-open if you think there's still more to do.

@shilman shilman closed this as completed Aug 19, 2020
@Hypnosphi
Copy link
Member

It still doesn't work with Flow type annotations. Should I open another issue?

@shilman
Copy link
Member

shilman commented Sep 13, 2020

cc @phated ☝️

@phated
Copy link
Contributor

phated commented Sep 13, 2020

@Hypnosphi can you provide a simple example of what you are doing with your story? I've not encountered this yet. I also think having a flow issue created would be helpful to separate from typescript since they are separate code paths.

@Hypnosphi
Copy link
Member

@phated it turned out not to be directly caused by type annotations: #12467

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