storybook: [7.0] Incompatible with sveltekit

Describe the bug A standard bootstrap of a sveltekit + storybook project fails to start.

To Reproduce

  • yarn create svelte
  • follow the prompts, choose skeleton for the template and no for everything else
  • yarn
  • npx sb@future init
  • yarn storybook
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /Users/ianvs/code/experiments/sveltekit-generator/node_modules/@sveltejs/adapter-auto/package.json

It seems like this happens because of a require call here: https://github.com/storybookjs/storybook/blob/b42f0edea70f4f97d1d64aa86945f3beeff2a7b7/code/lib/core-common/src/utils/interpret-require.ts#L24

But sveltekit is ESM-only. I tried changing the generated .storybook/main.cjs file into esm, but that still didn’t help.

System N/A

Additional context I’ve requested a way to specify all sveltekit options via command line flags, so that we can create a repro template for sveltekit and add it to our test suite: https://github.com/sveltejs/kit/issues/7064

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 40 (35 by maintainers)

Most upvoted comments

I’ll do a follow up PR that removes the SvelteKit Vite plugin.

Are there particular features you’re thinking of? If you don’t build the SvelteKit generated code such as the route handlers, I’m not sure you’re left with much…

I think it’s mainly importing the SvelteKit specific modules. I agree most of them don’t make sense in a deep component that you’d have in a Storybook story, eg. @sveltejs/kit/hooks doesn’t make sense in a Storybook context. But I can see some of them make sense, eg.:

  • $app/environment - As @Amerlander mentions should probably always be browser in SB
  • Supporting any $lib/ imports - I’d guess is just a simple Vite alias.
  • $app/paths - components showing the current URL or a path to an asset or whatever
  • $app/stores - the page and the navigation stores could be useful for components that navigates.

But I think all of these should ideally be treated similar to props (or “args”), so users could “mock” them or define them as needed per story. Setting the current page for a given story, or making $app/navigation/goto call a Storybook action when called. I think all of this is out of scope for our SvelteKit support for now, but I think it would be the ideal DX for anyone or the community to build.

My hunch is that the biggest annoyance would be that we don’t support $lib/ imports, I can see that being used quite often in any component.

I agree with benmccann. But I can give some examples for SvelteKit-specific code I used in my components and had to change to use with Storybook. It were only about the SvelteKit specific $app/environment browser variable and $app/stores page store:

I have a menu component which uses the page store:

import { page } from '$app/stores'
$: active = $page.url.pathname;

I haven’t thought about a workaround yet, I just decided to not add this component to storybook for now.

And I had components which used the browser variable to prevent code from being ssr. Those components are already changed to not use browser anymore and I think that also improved the components. Also, I think the browser variable for example could be hard coded to be always true in storybook and then easily be used.

I would rather prefer to be able to build storybook than to have these sveltekit specific things available.

In a perfect world the SvelteKit Vite plugin could be loaded with something like … plugins: [sveltekit({ server: false, builder: false })] … that would disable route handling as well as build outputs, etc.

That seems almost equivalent to removing the SvelteKit plugins, so would be roughly the same as doing:

if (!STORYBOOK) {
  config.plugins.push(sveltekit())
}

This could allow us to include the SvelteKit features* without having to battle with it for who gets to be the “main” handler.

  • (Although I can image some of the SvelteKit features would be impossible to include without Kit also being the main handler)

Are there particular features you’re thinking of? If you don’t build the SvelteKit generated code such as the route handlers, I’m not sure you’re left with much…

I think stripping out the SvelteKit plugin is probably a fine solution at least for now. I generally think that Svelte components should not be built containing SvelteKit-specific code. However, if folks have a use for it I’d be curious to hear about it as it’s something we could reconsider given a compelling usecase.

Weird, I’ve created latest basic sveltekit project and created some basic story, and when it tries to render it’s just that image

Also when I am using your config above I get config.server.fs.allow.push is not a function ERR! at config (/home/gbkwiatt/storybook/node_modules/@storybook/builder-vite/dist/vite-config.js:96:44) Above fixed when changing allow: to array ['.storybook'], but other error still persists

I’ve done an initial PR based on our discussions at https://github.com/storybookjs/storybook/pull/19338

I think it’s probably fine to filter out vite-plugin-svelte-kit, but I’m not sure it’s the only plugin you’ll encounter that has implemented configureServer. Will the others using that hook break too and you instead need some more general implementation that deletes that hook off all plugins? - @benmccann

vite-plugin-svelte actually also has a configureServer entry which sets up some watchers (https://github.com/sveltejs/vite-plugin-svelte/blob/main/packages/vite-plugin-svelte/src/index.ts#L98-L102), and I don’t think we want to exclude those, so that’s maybe a reason to not globally remove configureServer but just remove vite-plugin-svelte-kit instead?

I’m actually working on creating a repro template for SvelteKit and ran into the exact same issue as you did - see https://github.com/sveltejs/kit/pull/6982

The plan I’ve agreed upon with @ndelangen is that we’ll publish a small package that is just a wrapper around the create-svelte package so we can use the same methodology as we use with all our other repro templates.

that seems to go against your philosophy of not creating any custom scripts ourselves.

I agree that it’s not ideal, but since it’s such a simple wrapper that just passes arguments along I don’t think it’s a big deal. The biggest issue could be that we have to keep create-svelte up-to-date in that package which we usually don’t have to worry about when using npx. We could just gitignore the yarn.lock file to ensure we always use the latest create-svelte version, but that seem a bit hazardous so I’m hoping for better suggestions.

You can follow along with the progress at https://github.com/storybookjs/create-svelte-with-args - but as you can see I haven’t gotten very far. 😅 It is my main focus for now though, so should have something within the week.