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]: Failed to resolve module specifier "react" (@storybook/react-vite) #22630

Closed
unional opened this issue May 18, 2023 · 14 comments
Closed

Comments

@unional
Copy link
Contributor

unional commented May 18, 2023

Describe the bug

When running storybook dev, it is working fine.
But if it is built by running storybook build, and load the resulting index.html,

It fails with:

Failed to resolve module specifier "react". Relative references must start with either "/", "./", or "../".

image

To Reproduce

Do not have a repro yet

System

Environment Info:

  System:
    OS: macOS 13.3.1
    CPU: (10) arm64 Apple M1 Pro
  Binaries:
    Node: 16.19.0 - ~/.nvm/versions/node/v16.19.0/bin/node
    npm: 8.19.3 - ~/.nvm/versions/node/v16.19.0/bin/npm
  Browsers:
    Chrome: 113.0.5672.126
    Firefox: 112.0
    Safari: 16.4
  npmPackages:
    @storybook/addon-actions: ^7.0.12 => 7.0.12 
    @storybook/addon-backgrounds: ^7.0.12 => 7.0.12 
    @storybook/addon-console: ~2.0.0 => 2.0.0 
    @storybook/addon-docs: ^7.0.12 => 7.0.12 
    @storybook/addon-essentials: ^7.0.12 => 7.0.12 
    @storybook/addon-interactions: ^7.0.12 => 7.0.12 
    @storybook/addon-links: ^7.0.12 => 7.0.12 
    @storybook/addon-measure: ^7.0.12 => 7.0.12 
    @storybook/addon-outline: ^7.0.12 => 7.0.12 
    @storybook/addon-storysource: ~7.0.12 => 7.0.12 
    @storybook/addon-styling: ^1.0.8 => 1.0.8 
    @storybook/addons: ~7.0.12 => 7.0.12 
    @storybook/channel-postmessage: ^7.0.12 => 7.0.12 
    @storybook/channel-websocket: ^7.0.12 => 7.0.12 
    @storybook/client-api: ^7.0.12 => 7.0.12 
    @storybook/jest: ~0.1.0 => 0.1.0 
    @storybook/preview-web: ^7.0.12 => 7.0.12 
    @storybook/react: ^7.0.12 => 7.0.12 
    @storybook/react-vite: ^7.0.12 => 7.0.12 
    @storybook/test-runner: ~0.10.0 => 0.10.0 
    @storybook/testing-library: ^0.1.0 => 0.1.0 
    @storybook/theming: ^7.0.12 => 7.0.12

Additional context

I have also seen Failed to resolve module specifier "uuid", or Failed to resolve module specifier "some-library", where some-library is used in preview.tsx.

@Haschtl
Copy link

Haschtl commented May 19, 2023

I'm having a similar issue. dev working fine, but when I open the build, i'm getting

Failed to resolve module specifier "vite/modulepreload-polyfill". Relative references must start with either "/", "./", or "../".

@unional
Copy link
Contributor Author

unional commented Jun 6, 2023

This seems to occur after 7.0.7. I have one using that and it seems to be fine. The other one using 7.0.12 has this problem.

@unional
Copy link
Contributor Author

unional commented Jun 6, 2023

image

7.0.18

@shilman
Copy link
Member

shilman commented Jun 7, 2023

Do you a have a reproduction repo you can share? If not, can you create one? Go to https://storybook.new or see repro docs. Thank you! 🙏

@unional
Copy link
Contributor Author

unional commented Jun 7, 2023

Actually I do have a repro. https://github.com/justland/just-web-react

pnpm i
pnpm react sb:build

The folder will be in libraries/react/storybook-static

You can run the storybook dev by pnpm react sb. And you can see that is working fine.

@JReinhold
Copy link
Contributor

This is the result of the Vite builder being a bit too smart, and we have to workaround that.
The reason this error is happening, is because react is not bundled into the final bundle, but remains external, even in the Storybook build.

That's because Storybook automatically extends the user's vite.config, and in your case @unional, you're using rollup-plugin-node-externals to mark any devDependencies and peerDependencies as externals (which would be react)

In your case that makes sense, because you're building a library, and you don't want to include react in your library output. The problem is that you're also building an application (Storybook), which is a final bundle that can't have any externals at all.

The workaround is to remove the externals plugin with viteFinal in your main.ts configuration:

import type { StorybookConfig } from '@storybook/react-vite'
+ import { withoutVitePlugins } from '@storybook/builder-vite'

const config: StorybookConfig = {
	stories: ['../ts/**/*.stories.mdx', '../ts/**/*.stories.@(js|jsx|ts|tsx)'],
	addons: [
		'@storybook/addon-links',
		'@storybook/addon-essentials',
		'@storybook/addon-interactions',
		'@storybook/addon-storysource',
		'storybook-dark-mode',
		{
			name: '@storybook/addon-styling',
			options: {
				postCss: true
			}
		}
	],
	framework: {
		name: '@storybook/react-vite',
		options: {}
	},
	features: {
		storyStoreV7: true
	},
	typescript: {
		check: false
	},
	docs: {
		autodocs: true
	},
+	viteFinal: async config => {
+		return { ...config, plugins: await withoutVitePlugins(config.plugins, ['node-externals']) }
+	}
}

export default config

you also need to add @storybook/builder-vite as an explicit dev dependency, because you're using pnpm.

(If you test this out by serving your build output, make sure to reload the browser with DevTools open and caching disabled. The browser will aggressively cache the site, showing the error even if it has been fixed)

This is not the first time we run into this for library authors, and we want to improve the documentation and experience around this issue.

@unional
Copy link
Contributor Author

unional commented Jun 7, 2023

Thanks. Will try that.

But if that is the cause, why storybook dev is working fine?

Does that uses the cite config differently?

@JReinhold
Copy link
Contributor

But if that is the cause, why storybook dev is working fine?

That's because Vite only uses Rollup for production builds, and esbuild in development. And the plugin is a rollup-only plugin.

@unional
Copy link
Contributor Author

unional commented Jun 7, 2023

Would like to share that the library mode for vite is quite limited.
In another project, I use rollup directly to bundle, and use vite only for storybook.

It's more flexible and not impacted by this issue. :)

@JReinhold
Copy link
Contributor

@kylegach ultimately I think this is something we need to document, a quirk when using Vite and building a library, not an application.

I'll be happy to explain it in greater detail if my previous comment isn't enough.
I'm closing this issue though, as it isn't really a bug.

@JReinhold JReinhold closed this as not planned Won't fix, can't repro, duplicate, stale Sep 12, 2023
@steoneill
Copy link

I'm sadly having this issue still , after adding the vitefinal fix

@mehrdad-panahandeh
Copy link

mehrdad-panahandeh commented Nov 3, 2023

I replaced the build with swc and worked fine


import { dirname, join } from 'path'

/**
 * This function is used to resolve the absolute path of a package.
 * It is needed in projects that use Yarn PnP or are set up within a monorepo.
 */
function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, 'package.json')))
}
const config: StorybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-onboarding'),
    getAbsolutePath('@storybook/addon-interactions'),
  ],
  framework: {
    name: getAbsolutePath('@storybook/react-webpack5'),
    options: {
      builder: {
        useSWC: true,
      },
    },
  },
  docs: {
    autodocs: 'tag',
  },
}
export default config```

@mmospanenko
Copy link

"storybook": "^8.0.4"

same issue with Vite in lib mode (react as peerDependency)

@mmospanenko
Copy link

mmospanenko commented Mar 26, 2024

YEAH! Found solution, thanks @JReinhold!

  1. check what Vite "externals" plugin are you using for your Vite lib:
  viteFinal: async (config) => {
+  console.log('config', config.plugins);
    return {
      ...config,
      plugins: await withoutVitePlugins(config.plugins, ['peer-deps-external']),
    };
  },
image
  1. add this plugin ('peer-deps-external' in my case) to exclude list via withoutVitePlugins
  viteFinal: async (config) => {
    return {
      ...config,
+      plugins: await withoutVitePlugins(config.plugins, ['peer-deps-external']),
    };
  },

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

7 participants