Search code examples
reactjstypescriptstorybook

Storybook can't process TS files outside of the project


I have noticed that Storybook can't process Typescript files if they are from another project (monorepo), but it is doing okay with TS files that are within its project. How do I configure Storybook to handle TS files outside the project?

Structure of the monorepo:

package1
    .storybook
        main.ts
        preview.ts
    component.tsx (this component imports file.ts)
    component.stories.tsx
package2
    file.ts <- (Storybook can't process this file: ModuleParseError: Module parse failed: Unexpected token)

Here is the main.ts config file:

const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const path = require('path');
const toPath = (filePath) => path.join(process.cwd(), filePath);

module.exports = {
  "stories": [
    "../src/**/*.stories.@(mdx|js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    "@storybook/addon-knobs/register",
    "@storybook/preset-create-react-app",
    "@storybook/addon-a11y",
    'storybook-addon-styled-component-theme/dist/preset',
    'storybook-addon-themes',
    "storybook-dark-mode",
  ],
  "framework": "@storybook/react",
  "core": {
    "builder": "@storybook/builder-webpack5",
    "disableTelemetry": true,
  },
  features: {
    emotionAlias: false,
  },
  typescript: { reactDocgen: false },
  webpackFinal: async (config, { configType }) => {
    return {
      ...config,
      resolve: {
        ...config.resolve,
        alias: {
          ...config.resolve.alias,
          '@emotion/core': toPath('node_modules/@emotion/react'),
          'emotion-theming': toPath('node_modules/@emotion/react'),
        },
        plugins: [new TsconfigPathsPlugin()]
      },
    }
  }
}

Here is the error:

ModuleParseError: Module parse failed: Unexpected token (7:11)
File was processed with these loaders:
 * ../../node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
You may need an additional loader to handle the result of these loaders.
| import { Palette as palette } from '../Palette';
| 
> const Paper: any = [
|     {

If I import the same TS file, but manually precompiled into regular JS - Storybook works.

I have no idea what to try to solve this :(


Solution

  • Add this to .storybook/main.js

    webpackFinal: async (config, { configType }) => {
      // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
      // You can change the configuration based on that.
      // 'PRODUCTION' is used when building the static version of storybook.
    
      // Storybook uses its own webpack config, so we need to merge our config with it
      // See https://storybook.js.org/docs/configurations/custom-webpack-config/
    
      // Add typescript loader to process TS-files from other packages
      config.module.rules.push({
        test: /\.(ts|tsx)$/,
        use: [
          {
            loader: require.resolve("ts-loader"),
            options: {
              reportFiles: [
                "../**/src/**/*.{ts,tsx}"
              ]
            }
          },
        ]
      });
    
      config.resolve.extensions.push(".ts", ".tsx");
    
      return config;
    }