storybook: [Bug]: Zero-Config TypeScript Not Working After Upgrade from v6 to v7

Describe the bug

After following the migration guide from v6 to v7 I get errors seemingly related to TypeScript syntax being unrecognized.

To Reproduce

  1. Clone my demo repo https://github.com/NTARelix/sb7-no-config-ts
  2. Setup repo with nvm i && npm ci
  3. Start Storybook with npm start
  4. See error in console

System

Environment Info:

  System:
    OS: macOS 13.3.1
    CPU: (10) arm64 Apple M1 Pro
  Binaries:
    Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm
  Browsers:
    Chrome: 112.0.5615.137
    Firefox: 112.0.1
    Safari: 16.4
  npmPackages:
    @storybook/addon-essentials: ^7.0.7 => 7.0.7 
    @storybook/react: ^7.0.7 => 7.0.7 
    @storybook/react-webpack5: ^7.0.7 => 7.0.7

Additional context

In Storybook 6 all of this worked, presumably due to the Zero Config TypeScript support. After migrating to v7 the Storybook CLI describes a fatal error about syntax as if it doesn’t understand TypeScript. To confirm my suspicion I added a log statement to .storybook/main.ts which shows the generated Webpack 5 config, in which there seems to be no mention of TypeScript. I would expect to see .ts extension resolution and babel-loader or ts-loader.

It seems as though “Zero Config TypeScript” is no longer supported, but I can’t find anything in the migration docs regarding such a change.

I see a few possible causes/solutions:

  1. Zero config TypeScript is supposed to be present, but isn’t; feature must be re-added
  2. Zero config TypeScript was removed; migration docs must be updated
  3. Zero config TypeScript is present, but is not working as intended; bug fix must be released
  4. I missed a migration step, resulting in an invalid config for TypeScript support; my config must be updated

In any case, it will be easy enough for me to manipulate the Webpack config using webpackFinal() in .storybook/main.ts until there’s some kind of resolution to this.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 3
  • Comments: 15 (1 by maintainers)

Most upvoted comments

Following up with what I experienced - renaming the .babelrc.json file to babel.config.json as suggested here seemed to help a lot with TypeScript support. I have since ran into unrelated issues and ended up with a different Storybook config, this time based around Next.js.

Experiencing a similar issue in a React monorepo. I ran npx storybook@latest babelrc as suggested in the migration guide linked above, and it generated a .babelrc.json file with these options:

{
  "sourceType": "unambiguous",
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "chrome": 100
        }
      }
    ],
    "@babel/preset-typescript",
    "@babel/preset-react"
  ],
  "plugins": []
}

Still getting compilation errors when stories contain any TypeScript syntax, e.g.

SyntaxError: D:\[...]\Anchor.stories.tsx: Unexpected token, expected "," (50:2)
  48 |     }
  49 |   }
> 50 | } as Meta);
     |   ^

With a h/t to @kputnins, here is a full .storybook/main.ts example including TsConfigPathsPlugin to load paths from an alias in tsconfig.json:

import type { StorybookConfig } from "@storybook/react-webpack5";
import { Configuration, RuleSetRule } from "webpack";
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";

const config: StorybookConfig = {
  addons: ["@storybook/preset-create-react-app"],
  framework: "@storybook/react-webpack5",
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
  typescript: {
    // Removes babel-loader from webpack config
    skipBabel: true,
  },
  webpackFinal: async (config: Configuration) => {
    // Custom rule for ts files
    const tsRule: RuleSetRule = {
      test: /\.(tsx?|jsx?)$/,
      loader: "ts-loader",
      options: {
        transpileOnly: true,
      },
    };

    // tsconfig paths
    if (config.resolve) {
      config.resolve.plugins = [
        ...(config.resolve.plugins || []),
        new TsconfigPathsPlugin({
          extensions: config.resolve.extensions,
        }),
      ];
    }

    return {
      ...config,
      module: {
        ...config.module,
        rules: [...(config.module?.rules || []), tsRule],
      },
    };
  },
};

export default config;

Fwiw I found this issue after trying to automatically upgrade from SB 6 to 7. In my case, the migration seemed to mostly succeed but it never exited.

For anyone stumbling upon this - the override to the storybooks webpack config would be something like this

const config: StorybookConfig = {
    // ...
    typescript: {
        // Removes babel-loader from webpack config
        skipBabel: true,
    },
    webpackFinal: async (config: Configuration) => {
        // Custom rule for ts files
        const tsRule: RuleSetRule = {
            test: /\.(tsx?|jsx?)$/,
            loader: 'ts-loader',
            options: {
                transpileOnly: true,
            },
        };

        return {
            ...config,
            module: { ...config.module, rules: [...(config.module?.rules || []), tsRule] },
        };
    },
};

@shilman When I created this issue I couldn’t get the automigration feature to work (it works now), so I followed the manual migration guide. Looking through the guide I see a reference to “providing your own Babel config”, but my project used tsc instead of Babel. This explains why this was broken for me. Based on the various comments here I’m confident this isn’t a bug and I can continue with Storybook v7 by either migrating to Babel or manipulating the Webpack config with webpackFinal to replace babel-loader with ts-loader.

@joshuajaco Using webpackFinal I logged the existing Webpack config and confirmed that babel-loader is the only TypeScript loader provided by default, but it would be easy to replace this loader with something like ts-loader. https://storybook.js.org/docs/react/builders/webpack#override-the-default-configuration

That’s correct. We changed the way Babel is handled. During the 7.0 automigration if you don’t have a babelrc, the migration tool can automatically create one for you with Typescript support built in. If you don’t choose that option, we don’t support TS.

More info: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#babel-mode-v7-exclusively

If I am pasting same stories under “stories” folder (got created while storybook 7 installation), stories are working fine. But I need to keep stories under each component folders(Button, Icon, Checkboax, etc.)