飽き性の頭の中

tsconfigとStorybook(Vite)のpathのエイリアスがズレていてエラーになった|Remix, Panda CSS, Storybook

tsconfigとStorybook(Vite)のpathのエイリアスがズレていてエラーになった|Remix, Panda CSS, Storybook

tawachan
tawachan

Remix で Panda CSS を使うのを試していたときに、Storybook も入れたのだが、少し手間だったのでそのときのメモ。

考えれば至極当たり前なのだが、少し手間だったので作業ログとして残しておく。

Panda CSS を使った Remix のプロジェクト

Remix の./appディレクトリや、Panda CSS のstyled-systemディレクトリへのエイリアスを設定することが多いと思う。

そうした設定は、tsconfig.jsonに入っているはずだが、たとえば次のようになっているとする。

   {
  "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
  "compilerOptions": {
    "lib": ["DOM", "DOM.Iterable", "ES2022"],
    "isolatedModules": true,
    "esModuleInterop": true,
    "jsx": "react-jsx",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "target": "ES2022",
    "strict": true,
    "allowJs": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "baseUrl": ".",
    "paths": {
      "~/*": ["./app/*"],
      "~/s/*": ["./styled-system/*"]
    },
    // Remix takes care of building everything in `remix build`.
    "noEmit": true
  }
}

Storybook のエラー

何もせずにこのプロジェクトに Storybook を入れると、次のようなエラーが出る。

   🐼 info [hrtime] Extracted in (6.85ms)
21:01:51 [vite] Pre-transform error: Failed to resolve import "~/s/css" from "app/components/Header.tsx". Does the file exist?
21:01:51 [vite] Internal server error: Failed to resolve import "~/s/css" from "app/components/Header.tsx". Does the file exist?
  Plugin: vite:import-analysis
  File: /Users/****/your-project/app/components/Header.tsx:1:29
  14 |    window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
  15 |  }
  16 |  import { css } from "~/s/css";
     |                       ^
  17 |  import { stack } from "~/s/patterns";
  18 |  export const Header = () => {
      at formatError (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:50510:46)
      at TransformContext.error (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:50504:19)
      at normalizeUrl (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:65561:33)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:65716:47
      at async Promise.all (index 3)
      at async TransformContext.transform (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:65637:13)
      at async Object.transform (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:50819:30)
      at async loadAndTransform (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:53592:29)
      at async viteTransformMiddleware (file:///Users/****/your-project/node_modules/vite/dist/node/chunks/dep-94_H5fT6.js:63376:32)

Storybook の設定

最近だと、Storybook は Vite で動かすことが多いと思う。そうすると、Vite の方にも別途エイリアスの設定が必要になる。

その設定がないから以上のエラーが出ているということだ。

Storybook は Vite の設定が露出していないので、main.tsで Vite の設定を上書きする必要がある。

今回は、vite-tsconfig-pathsを使って、tsconfig.jsonpathsを Vite のエイリアスとして使うことにした。

   import type { StorybookConfig } from "@storybook/react-vite";
import { mergeConfig } from "vite";
// このライブラリを使うと、tsconfig.jsonのpathsをViteのエイリアスとして使える
import tsconfigPaths from "vite-tsconfig-paths";

const config: StorybookConfig = {
  stories: ["../app/components/**/*.stories.@(ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-onboarding", "@storybook/addon-interactions"],
  framework: {
    name: "@storybook/react-vite",
    options: {},
  },
  docs: {
    autodocs: "tag",
  },
  // 以下がViteの設定
  async viteFinal(config) {
    return mergeConfig(config, {
      // ここにresolve.aliasを追加してもよいが、手間なのでライブラリでtsconfig.jsonのpathsと揃えられるようにした
      plugins: [tsconfigPaths()],
    });
  },
};
export default config;

そうすると、Storybook でもエイリアスが使えるようになる。

まとめ

別に、Remix とか Storybook とか Panda CSS とかに限らない問題ではある。

ただ、tsconfig のエイリアスと Vite のエイリアスの設定が揃っていないと、エラーが出るということだ。

関連記事