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

[Bug]: HMR of preview.tsx is not working #26881

Open
hirotomoyamada opened this issue Apr 19, 2024 · 1 comment
Open

[Bug]: HMR of preview.tsx is not working #26881

hirotomoyamada opened this issue Apr 19, 2024 · 1 comment

Comments

@hirotomoyamada
Copy link

Describe the bug

After upgrading to v8, HMR no longer works for preview.tsx.

To Reproduce

preview.tsx

import React from "react"
import { Decorator, Parameters } from "@storybook/react"
import { themes } from "@storybook/theming"
import { UITheme } from "./theme"
import { StoryProvider, DocsContainer } from "./components"

export const parameters: Parameters = {
  darkMode: {
    light: { ...themes.light, ...UITheme.light },
    dark: { ...themes.dark, ...UITheme.dark },
  },
  options: {
    storySort: {
      order: ["Documents", ["Welcome", "*"], "Components", "Hooks", "System"],
    },
  },
  a11y: {
    config: {
      rules: [
        { id: "color-contrast", enabled: false },
        { id: "landmark-unique", enabled: false },
      ],
    },
  },
  backgrounds: { disable: true },
  controls: { expanded: true },
  docs: { container: DocsContainer },
  layout: "fullscreen",
}

export const decorators: Decorator[] = [
  (Story) => {
    return (
      <StoryProvider>
        <Story />
      </StoryProvider>
    )
  },
]

components.tsx

import React, { FC, ReactNode, useEffect } from "react"
import { useDarkMode } from "storybook-dark-mode"
import {
  Container,
  ContainerProps,
  UIProvider,
  useColorMode,
} from "@yamada-ui/react"
import {
  DocsContainer as StorybookDocsContainer,
  DocsContainerProps,
} from "@storybook/blocks"
import { themes } from "@storybook/theming"

export const StoryProvider: FC<{ children: ReactNode }> = ({ children }) => {
  return (
    <UIProvider>
      <App p="md">{children}</App>
    </UIProvider>
  )
}

const App: FC<ContainerProps> = ({ p, children }) => {
  const { changeColorMode } = useColorMode()

  const colorMode = useDarkMode() ? "dark" : "light"

  useEffect(() => {
    changeColorMode(colorMode)
  }, [colorMode])

  return (
    <Container p={p} gap="md" alignItems="flex-start">
      {children}
    </Container>
  )
}

export const DocsContainer: FC<
  DocsContainerProps & { children: ReactNode }
> = ({ children, theme, ...rest }) => {
  const dark = useDarkMode()

  theme = dark ? themes.dark : themes.light

  return (
    <StorybookDocsContainer theme={theme} {...rest}>
      {children}
    </StorybookDocsContainer>
  )
}

Until v7, updating the StoryProvider in the decorators, i.e. UIProvider, made HMR work.

System

System:
    OS: macOS 14.4.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.0 - ~/.nodenv/versions/20.11.0/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 10.2.4 - ~/.nodenv/versions/20.11.0/bin/npm
    pnpm: 8.13.1 - /usr/local/bin/pnpm <----- active
  npmPackages:
    @storybook/addon-a11y: ^8.0.8 => 8.0.8 
    @storybook/addon-backgrounds: ^8.0.8 => 8.0.8 
    @storybook/addon-docs: ^8.0.8 => 8.0.8 
    @storybook/addon-measure: ^8.0.8 => 8.0.8 
    @storybook/addon-storysource: ^8.0.8 => 8.0.8 
    @storybook/addon-viewport: ^8.0.8 => 8.0.8 
    @storybook/blocks: ^8.0.8 => 8.0.8 
    @storybook/cli: ^8.0.8 => 8.0.8 
    @storybook/manager-api: ^8.0.8 => 8.0.8 
    @storybook/react: ^8.0.8 => 8.0.8 
    @storybook/react-vite: ^8.0.8 => 8.0.8 
    @storybook/theming: ^8.0.8 => 8.0.8 
    storybook: ^8.0.8 => 8.0.8 
    storybook-dark-mode: ^4.0.1 => 4.0.1

Additional context

No response

@hirotomoyamada
Copy link
Author

Currently, as a countermeasure, I am using a plugin called force-reload-on-specific-files to reload.

import type { StorybookConfig } from "@storybook/react-vite"
import { InlineConfig, UserConfig, mergeConfig } from "vite"
import path, { dirname, join } from "path"

const config: StorybookConfig = {
  framework: getAbsolutePath("@storybook/react-vite"),

  core: {
    disableTelemetry: true,
  },

  stories: ["../stories/**/*.@(mdx|stories.@(tsx))"],

  addons: [
    getAbsolutePath("@storybook/addon-viewport"),
    getAbsolutePath("@storybook/addon-docs"),
    getAbsolutePath("@storybook/addon-a11y"),
    getAbsolutePath("@storybook/addon-backgrounds"),
    getAbsolutePath("@storybook/addon-measure"),
    getAbsolutePath("@storybook/addon-storysource"),
    getAbsolutePath("storybook-dark-mode"),
  ],

  viteFinal: async (config) => {
    config = mergeConfig<InlineConfig, UserConfig>(config, {
+       plugins: [
+         {
+           name: "force-reload-on-specific-files",
+           handleHotUpdate: ({ file, server }) => {
+             const isTheme = file.startsWith(
+               path.resolve(__dirname, "../packages/theme/src"),
+             )
+             const isProviders = file.startsWith(
+               path.resolve(__dirname, "../packages/providers/src"),
+             )
+
+             if (isTheme || isProviders) {
+               server.hot.send({ type: "full-reload" })
+             }
+           },
+         },
+       ],
      resolve: {
        alias: [
          {
            find: /\@yamada-ui\/react$/,
            replacement: path.resolve(__dirname, "../packages/react/src"),
          },
          {
            find: /\@yamada-ui\/theme$/,
            replacement: path.resolve(__dirname, "../packages/theme/src"),
          },
        ],
      },
    })

    config.esbuild = undefined

    return config
  },

  typescript: {
    reactDocgen: false,
  },
}

export default config

function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, "package.json")))
}

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

1 participant