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

preset-typescript does not work according to instructions #65

Open
rpolonsky opened this issue Nov 22, 2019 · 17 comments
Open

preset-typescript does not work according to instructions #65

rpolonsky opened this issue Nov 22, 2019 · 17 comments
Labels
bug Something isn't working typescript

Comments

@rpolonsky
Copy link

rpolonsky commented Nov 22, 2019

I have a clean setup for storybook/react: npx -p @storybook/cli sb init --type react
I added preset-typescript to new presets.js file like that module.exports = ['@storybook/preset-typescript']; and dependencies npm i -D @storybook/preset-typescript react-docgen-typescript-loader ts-loader

Now I have quite a simple basic configuration:

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

// automatically import all files ending in *.stories.js
configure(require.context('../stories', true, /\.stories\.ts$/), module);

/*.storybook/presets.js*/
module.exports = ['@storybook/preset-typescript'];
/*.storybook/addons.js*/
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';

/*stories/0-Welcome.stories.ts*/

import React from 'react';
import { linkTo } from '@storybook/addon-links';
import { Welcome } from '@storybook/react/demo';

export default {
  title: 'Welcome',
};

export const toStorybook = () => <Welcome showApp={linkTo('Button')} />;

toStorybook.story = {
  name: 'to Storybook',
};

And instruction says that's it, but:
Screenshot 2019-11-22 at 14 06 33

So how does it work?

@shilman
Copy link
Member

shilman commented Nov 24, 2019

@rpolonsky what happens when you name that 0-Welcome.stories.tsx?

@shilman shilman added question Further information is requested typescript labels Nov 24, 2019
@adam-beck
Copy link

adam-beck commented Nov 27, 2019

I'm running into the same problem. Changing the extensions from .ts to .tsx did not solve the issue.

I was trying to create the smallest reproduction inside of a Next.js app. I think the issue stems from an incompatible tsconfig.json. And since the documentation doesn't hint at the necessary configuration options, Storybook fails to transpile the Typescript code.

For reference, here is my tsconfig.json that works:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false,
    "jsx": "react"
  },
  "include": ["src", "stories"]
}

A few notes:

  1. "jsx" is set to "react" and not "preserve"
  2. Although I am trying to setup within a Next.js app, I stole this config file from create-react-app's tsconfig.json
  3. I changed the value of "noEmit" from true to false
  4. I appended "stories" to the "include" array
  5. For the demo to work, I needed to supply custom type definitions for the '@storybook/react/demo' components - as TS complained. However, this is likely due to the "strict" option being true It was caused by the "strict" option.

@shilman
Copy link
Member

shilman commented Nov 27, 2019

@adam-beck Thanks for the thorough diagnosis! 🙌 How would you recommend improving the docs for your use case?

@adam-beck
Copy link

adam-beck commented Nov 27, 2019

For starters, it might be best to ensure that the tsconfig.json file that comes with the preset works (without error) for a clean (i.e. npx -p @storybook/cli sb init) Storybook setup. Since it uses the rule "noImplicitAny": true,, it fails to compile since there are no typings for the demo components. Either the typings should be generated or the rule should be toggled to false. I think the former would be the ideal solution but the latter would be much easier.

The documentation could also mention which configuration options are absolutely necessary such as "jsx": "react". The smallest tsconfig.json I could create and still get it to work is:

{
  "compilerOptions": {
    "module": "es6",
    "jsx": "react",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true
  }
}

It may be worthwhile to mention that those need to be set as is.

Other than that, though, it's hard because each project has a unique tsconfig.json. It would be impractical to include even a fraction of the scenarios. I would suggest advising that

  • any existing tsconfig.json will likely need to be overridden & include an example of doing so (it sort of already does this)
  • explain that if the application already has a .storybook/config.js it will need to be changed to search for .tsx? files

Edit: It looks like the demo components have typings already! I'm not sure why they aren't being picked up though. After searching, it looks like this has already been fixed too!

@daraclare
Copy link

Hi have the same issue, however the tsconfig file did not work for me. We keep our stories in folders in with the component, would this make a difference? Below is a the error, looks like nothing is being transpiled using this preset.
Screenshot 2019-12-20 at 11 41 09

@thedaviddias
Copy link

I'm having the same issue, tried from scratch a few times, but having the same issue that @daraclare has.

@CallumJHays
Copy link

Bump. Me three.
image

tsconfig:
image

@wollardj
Copy link

It looks to me like the problem is with the underlying webpack config. Running npx start-storybook --debug-webpack when presets.js only has module.exports = ["@storybook/preset-typescript"]; produces the following:

// ...
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: '/Users/joe/Projects/test/node_modules/ts-loader/index.js',
            options: { transpileOnly: true }
          },
          {
            loader: '/Users/joe/Projects/test/node_modules/react-docgen-typescript-loader/dist/index.js',
            options: {}
          }
        ],
        include: []
      },
// ...

Notice the empty include array. But, if you change presets.js such that include is specified...

const path = require("path");

module.exports = [
  {
    name: "@storybook/preset-typescript",
    options: {
      include: [
        path.resolve(__dirname, "../src"),
        path.resolve(__dirname, "../stories")
      ]
    }
  }
];

... everything works as expected and the relevant portion of the webpack config has the correct include directive:

// ...
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: '/Users/joe/Projects/test/node_modules/ts-loader/index.js',
            options: { transpileOnly: true }
          },
          {
            loader: '/Users/joe/Projects/test/node_modules/react-docgen-typescript-loader/dist/index.js',
            options: {}
          }
        ],
        include: [
          '/Users/joe/Projects/test/src',
          '/Users/joe/Projects/test/stories'
        ]
      },
// ...

Just for the sake of comparison, I checked the generated webpack config in a CRA project and found that it's using this:

// ...
        test: /\.(js|mjs|jsx|ts|tsx)$/,
        include: [
          '/Users/joe/Projects/cra-test/src',
          '/Users/joe/Projects/cra-test/.storybook'
        ],
// ...

I'm not sure why the include array is empty when the directions for installing this preset are followed as published, but I'm reasonably sure that's the issue.

@wollardj
Copy link

Looks like include defaults to an empty array here: https://github.com/storybookjs/presets/blob/master/packages/preset-typescript/index.js#L9

If we can take a note from CRA, maybe it could default to something more like this:

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
...
include = [
  resolveApp('src'),
  resolveApp('stories'),
  resolveApp('.storybook')
]

@wollardj
Copy link

I was gonna create a fork and throw up a pull request for this, but it looks like that's already being addressed by @T0MASD in #83 👍

@kevinbarabash
Copy link

@wollardj I struggled trying to get this to work for a long time before I found this issue. Setting options.include on the @storybook/preset-typescript plugin did the trick. Thank you!

@agdespopoulos
Copy link

Looks like include defaults to an empty array here: https://github.com/storybookjs/presets/blob/master/packages/preset-typescript/index.js#L9

If we can take a note from CRA, maybe it could default to something more like this:

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
...
include = [
  resolveApp('src'),
  resolveApp('stories'),
  resolveApp('.storybook')
]

Good catch! I had been frustrated with this for a while, but setting these in options.include on the preset, as @kevinbarabash said, fixed it for me. Thanks!

@shilman shilman added bug Something isn't working and removed question Further information is requested labels Jan 16, 2020
@kylemh
Copy link
Member

kylemh commented Jan 20, 2020

Trying to integrate Storybook as a part of a TSDX component library.

Steps I took:

  1. npx -p @storybook/cli sb init --type react

  2. yarn add -D @storybook/preset-typescript react-docgen-typescript-loader ts-loader fork-ts-checker-webpack-plugin

  3. Convert .storybook/main.js to:

module.exports = {
  stories: ['../src/components/**/*.stories.(tsx|mdx)'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  presets: ['@storybook/preset-typescript'],
};
  1. Created the following Button.stories.tsx within src/components/Button/__stories__/:
import React from 'react';
import { action } from '@storybook/addon-actions';
import { Button } from '../';

export default {
  title: 'Button',
  component: Button,
};

export const WithRequiredProps = () => (
  <Button onClick={action('clicked')}>Click me!</Button>
);

After I run, yarn storybook, I get the following:
Screen Shot 2020-01-19 at 5 13 05 PM


I ditched the preset and got everything working with this:

  1. npx -p @storybook/cli sb init --type react

  2. yarn add -D yarn add -D awesome-typescript-loader @storybook/addon-info react-docgen-typescript-loader

  3. .storybook/main.js:

module.exports = {
  stories: ['../src/**/*.stories.(tsx|mdx)'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal: async (config) => {
    config.module.rules.push({
      test: /\.(ts|tsx)$/,
      use: [
        {
          loader: require.resolve('awesome-typescript-loader'),
        },
        {
          loader: require.resolve('react-docgen-typescript-loader'),
        },
      ],
    });

    config.resolve.extensions.push('.ts', '.tsx');

    return config;
  },
};

@dizefurkan
Copy link

dizefurkan commented Jun 8, 2020

I spend two work day for solve this issue. Then finally i solved it. Here is my solution step by step:

First, i follow the for installing storybook Then i look up for typescript/cra support. doc
They are recommend @storybook/preset-create-react-app to use preset for CRA (also support typescript/cra). There is no much config, the project directly started BUT when i change the file extension (.js to .tsx) i faced that error.

Screen Shot 2020-06-08 at 10 39 27

  1. I install the ts-loader Setting up TypeScript with ts-loader
  2. Edit storybook/main.js Setting up TypeScript with babel-loader
module.exports = {
  stories: ['../src/components/**/*.stories.tsx'],
  webpackFinal: config => {
    config.module.rules.push({
      test: /\.(ts|tsx)$/,
      loader: require.resolve('babel-loader'),
      options: {
        presets: [['react-app', { flow: false, typescript: true }]],
      }
    });
    config.resolve.extensions.push('.ts', '.tsx');
    return config;
  },
};

stories: ['../src/components/**/*.stories.tsx'],
Note: Stories path can change. Each story placed inside the component folder

Then Install following packages:
npm install --save-dev babel-loader babel-preset-react-app

  1. Start App npm run storybook
    Then i faced new error:

Screen Shot 2020-06-08 at 12 17 15

Screen Shot 2020-06-08 at 12 18 22

Problem is resolve path alias. You can solve this error like that:
import Text from 'components/text'; to import Text from '../../text';

But i don't want to do that. That's why i add that config to .storybook/main.js:

resolve: {
  alias: {
    components: path.resolve(__dirname, '../src/components'),
    styles: path.resolve(__dirname, '../src/styles'),
  }
}

Then Boom:
Screen Shot 2020-06-08 at 12 22 37

Note: There is no tricky things. I just follow the manual installation on storybook.
By the way, thanks for this beautiful project.

@kylemh
Copy link
Member

kylemh commented Jun 9, 2020

This should be improved when v6 is released 🙏

@IronSean
Copy link

IronSean commented May 18, 2021

@kylemh was it? I'm trying to get everything working but things blow up when I add @storybook/preset-typescript

@kylemh
Copy link
Member

kylemh commented May 18, 2021

in v6, typescript support is internal

you're not meant to use the preset

https://storybook.js.org/docs/react/configure/typescript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working typescript
Projects
None yet
Development

No branches or pull requests