Closed IanVS closed 2 years ago
Bummer, my issue in sveltekit got closed already. This is maybe a downside of relying on community-generators, @ndelangen. What should we do when they don't expose command-line flags? Their suggestion is to write a script that uses their node api, but that seems to go against your philosophy of not creating any custom scripts ourselves.
cc @benmccann just for your awareness of this issue, and our difficulty in adding sveltekit to our CI process.
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.
Progress update from me.
I managed to release create-svelte-with-args
and integrate it into our new repro template setup in the https://github.com/storybookjs/storybook/tree/jeppe/sb-544-sveltekit branch.
I run into the same CJS issue as you @IanVS, but I'm able to bypass it by commenting out the require call in the .storybook/main.cjs
file:
// repros/svelte-kit/skeleton-js/after-storybook/.storybook/main.cjs
const path = require('path');
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/svelte-vite',
options: {},
},
svelteOptions: {
// "preprocess": require("../svelte.config.js").preprocess
},
};
We need to make this work of course, but one problem at a time.
The weird think I'm experiencing now is when running the storybook
script with yarn storybook
(alias for npx storybook dev -p 6006
) it just opens the regular SvelteKit app, no Storybook UI in sight. But the terminal output looks fine:
@storybook/cli v7.0.0-alpha.34
info => Loading presets
info => Loading presets
info => Loading presets
info => Starting manager..
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ Storybook 7.0.0-alpha.34 for svelte-vite started โ
โ 905 ms for manager and 894 ms for preview โ
โ โ
โ Local: http://localhost:6006/ โ
โ On your network: http://192.168.1.189:6006/ โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
AND http://localhost:6006/project.json
actually returns a valid JSON file, the only suspicious thing being that it lists "webpack5"
as the builder.
I'll keep digging into this and figure out what's going on. My hunch is that the vite-builder somehow picks up the wrong application.
I wouldn't worry too much about making svelteOptions.preprocess
work. I would highly discourage use of that option and would not mind removing it. builder-vite
will now read the svelte.config.js
itself so we shouldn't make the user be responsible for it (https://github.com/storybookjs/builder-vite/pull/428).
@JReinhold thanks for the update! As for storybook launching the app, it's something we've seen before, and it should have been fixed in https://github.com/storybookjs/builder-vite/pull/453. I'd start by taking a look there to see if that option isn't getting set correctly now for some reason. I can dig into this as well in a day or two.
Yeah that makes sense @benmccann, So essentially what we want to do is change the template so the "preprocess": require("../svelte.config.js").preprocess
isn't part of main.cjs
when we do sb init
- right?
Thanks for the tip about appType
@IanVS, but it wasn't it. I've figured out that the issue is caused by Storybook's Vite server merging ยดbuilder-viteยด's own config with the "user's" (ie. the config in the sandbox) Vite config, which just adds the SvelteKit plugins to the config. I think the middlewares added by vite-plugin-svelte-kit
gets first priority over everything else in the server, intercepting requests.
Commeting out the SvelteKit plugin in the sandbox's vite.config.js
will make Storybook manager appear fine but all stories errors out with bad formatting, presumably because it doesn't compile Svelte now that SvelteKit's Vite plugin isn't added.
However, if we remove the plugin specific to SvelteKit - vite-plugin-svelte-kit
- but keep all the default svelte plugins plugins, Storybook actually works with all stories functioning. Here's how I achieved this in viteFinal
in main.cjs
:
viteFinal: (config) => {
+ const sveltePluginsWithoutKit = config.plugins[0].filter(
+ (plugin) => plugin.name !== 'vite-plugin-svelte-kit',
+ );
const finalConfig = {
...config,
optimizeDeps: {
...config.optimizeDeps,
force: true,
},
};
+ finalConfig.plugins[0] = sveltePluginsWithoutKit;
return finalConfig;
},
I'm pretty sure this is not the right path forward, but it pinpoints the problem at least. I'm wondering if we want to somehow load vite-plugin-svelte-kit
, or if we don't want that. I'd assume that it's mostly about routing and pages which doesn't make much sense within Storybook anyway, but it might also add stuff like the global stores and env that might break certain Components if they don't exist? What's your thoughts on this @benmccann ?
As a side note I assume that the reason this works in a barebone Svelte Vite app is because those Vite configs have all the necessary Svelte Vite plugins added while SvelteKit has both Svelte + SvelteKit, and thus by removing the SvelteKit plugin we're back to a barebone Svelte Vite app.
@JReinhold Let me know if you want to discuss this in a tuple or zoom or something ๐
I did some poking around, and it seems to be the configureServer
hook that sveltekit adds which is causing the app to be served instead of storybook. @benmccann do you know of any way we can prevent this within storybook? I think we want to keep the sveltekit plugin, rather than filtering it out, right?
@IanVS you're right actually, I figured out an easy way to remove that. It also requires allowing our root directory because otherwise preview.js
is denied. ( we could probably fine tune this)
I got a very crude PoC to work by changing the viteFinal
function in code/frameworks/svelte-vite/src/preset.ts
to:
export const viteFinal: StorybookConfig['viteFinal'] = async (config, { presets }) => {
const { plugins = [] } = config;
plugins.push(svelteDocgen(config));
// plugins[0][2] is the vite-plugin-svelte-kit
delete plugins[0][2].configureServer;
// maybe also delete plugins[0][2].configurePreviewServer; ?
return {
...config,
plugins,
server: {
...config.server,
fs: {
...config.server.fs,
allow: ['.'],
},
},
};
};
I'll investigate further later, just wanted to keep you up-to-date
It looks like we lost this custom plugin in the move to 7.0: https://github.com/storybookjs/builder-vite/pull/427.
Though, I'm not sure it will work in this case, since the sveltekit plugin is using a config
hook to add the allow list, so it won't show up in the config
in viteFinal
.
I think maybe we need to check for the presence of the sveltekit plugin, and if found, add .storybook
to the allow list and delete the configureServer
. If we end up having to do too much more config, I wonder if eventually we'll want sveltekit to have its own storybook framework, rather than adding a bunch of conditional logic into the svelte-vite framework. As far as I know, that was kind of the point of the framework refactor. And in fact, svelte themselves could publish a storybook framework that's tailored to meet their needs.
I'm surprised configureServer
is causing issues in 7.0, but not 6.0. Here's an example 6.0 project.
But anyway, I'm fairly skeptical that people should be writing SvelteKit-specific components. I almost think it's better that it's broken when you try to use SvelteKit functionality as it will force you to better structure your components. If you're writing Svelte components I'd generally expect them to work in any Svelte project and not just SvelteKit projects.
I could see it being a bit annoying to people that they can't do import { browser, dev, prerendering } from '$app/environment';
. But this is also a problem we have when users run svelte-kit package
to bundle their libraries for deployment (e.g. https://github.com/sveltejs/kit/issues/1950 and https://github.com/sveltejs/kit/issues/5879), so I think we need a more general solution.
For now, I would say as long as Svelte libraries work, we're probably best off ignoring SvelteKit issues.
Adding .storybook
to the fs allow list sounds like something that should be handled in the Storybook Vite builder regardless of whether you're using SvelteKit as it doesn't have anything to do with SvelteKit.
@benmccann thanks, I agree we need to handle the fs.allow, likely by porting your plugin from the PR I linked into 7.0 (not sure how it got lost).
And to be clear on your other point, are you suggesting that we should filter out the vite-plugin-svelte-kit
plugin entirely?
I don't quite understand yet why vite-plugin-svelte-kit
would break things with 7.0, but not 6.0. Is 7.0 starting a Vite dev server where 6.0 was not? 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?
I don't quite understand yet why vite-plugin-svelte-kit would break things with 7.0, but not 6.0. Is 7.0 starting a Vite dev server where 6.0 was not?
I'm pretty stumped by this as well. Not that much changed in the vite builder, mostly just that we read the vite.config.js automatically, and I found a few other minor differences as well, but no matter what I do I can't get 6.5 to reproduce the behavior of 7.0 or vice-versa. Very weird...
The only thing I can think of is that in 7.0, the storybook ui itself is built using esbuild, whereas before it was bundled with webpack. It's a stretch, but maybe that's got something to do with it?
Adding /iframe.html
to the url does seem to at least try to load stories, though it fails for a reason I don't understand so far...
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 implementedconfigureServer
. 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've done an initial PR based on our discussions at https://github.com/storybookjs/storybook/pull/19338
Ideally we wouldn't have to remove anything. We don't need to with 6.5, and I'm trying to figure out what's different about 7.0.
I think I've figured out why SvelteKit breaks in 7.0 but not in 6.5.
As you say @IanVS, builder-vite
automatically loads the user's vite.config.js
in 7.0 but not in 6.5. And in 6.5 we manually load the necessary Svelte Vite plugins, which doesn't include vite-plugin-svelte-kit
. This means that in 6.5 we actually never load vite-plugin-svelte-kit
, even in a SvelteKit app. But because of the auto-loading in 7.0 (which I think is a good thing) we get it there, and then it causes us troubles.
My steps were:
npx create-svelte@latest
npx sb init
svelteOptions
from main.cjs
(see below)console.dir(finalConfig, { depth: 10 })
just before createServer()
in node_modules/@storybook/builder-vite/dist/vite-server.js
which I think is the last possible place to log it.vite-plugin-svelte-kit
plugin.vite.config.js
like:const config: UserConfig = {
plugins: [sveltekit(), { name: "jeppes-custom-vite-plugin" }],
};
So I think that we should continue with our current solution for now because it works as it used to, and if we want more of the SvelteKit goodness like importing globals and envs, the SvelteKit team would have to separate that functionality from the route handling functionality for us to be able to extract that. (not saying I expect this to happen, just saying it's the only option I see in that regard)
svelteOptions
As my PR for 7.0 removes the svelteOptions
in main.cjs
to fix the CJS vs ESM issue we actually need to do something similar for 6.5, because right now it doesn't work if you/the user don't remove that line manually.
However I'm not sure we can actually do that in 6.5 because I don't think the options are auto-loaded by Vite/the Vite builder in 6.5 as they are in 7.0, so I'm afraid removing that will mean that we won't have the user's custom svelteOptions
in their Storybook. I could be wrong here though, please correct me.
I'm not sure what the correct way forward here is actually, other than telling SvelteKit users that they have to wait for 7.0 to land? I hoped there were a quick win to make 6.5 work though.
@JReinhold even when including sveltekit plugin in 6.5, this issue didn't happen. Ben pointed to a 6.5 example sveltekit app with storybook in the issue, and it works correctly.
And yes, the vite builder does load svelteoptions itself in 6.5.
@IanVS you're right, I totally missed that. Then I'm all out of clues, I even tried to do a file-by-file comparison between vite-builder
6.5 and 7.0 and came up empty handed. I also tried to move the SvelteKit plugin loading further up the chain in 6.5 because I thought that maybe the order of the plugins had an effect, but it didn't.
Yeah, I tried things like that, even removing all other plugins and making sure the rest of the vite config was identical. That's why the only thing I can think of is that it has something to do with the change moving the manager away from weback and to esbuild, though as far as I can tell, the dev server is unchanged and is still just an express server.
Just to make sure this issue here is related.
I am trying to deploy sveltekit storybook with latest storybook alpha and alpha @storybook/svelte-vite
as per default configuration.
But upon web preview I get Expected your framework's preset to export a
renderToDOMfield.
Is that what you are trying to sort out here or it's not related ?
@gbkwiatt that looks like a different error. I was able to bootstrap a new sveltekit project, run npx sb@next init
, and then tweak the .storybook/main.cjs
file a little:
const {mergeConfig} = require('vite');
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx|svelte)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
],
"framework": {
"name": "@storybook/svelte-vite",
"options": {}
},
viteFinal(config) {
return mergeConfig(config, {
server: {
fs: {
allow: ['.storybook'],
}
}
})
}
}
and storybook started up successfully after that.
This workaround in the main.cjs
will only be needed until https://github.com/storybookjs/storybook/pull/19338 is updated and released.
Weird, I've created latest basic sveltekit project and created some basic story, and when it tries to render it's just that
~~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
@gbkwiatt can you share the output of npx sb@next info
? I wonder if you have an old storybook package hanging around somehow.
npx sb@next info
System:
OS: Linux 5.10 Ubuntu 20.04.4 LTS (Focal Fossa)
CPU: (16) x64 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
Binaries:
Node: 18.1.0 - ~/.nvm/versions/node/v18.1.0/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v18.1.0/bin/yarn
npm: 8.8.0 - ~/.nvm/versions/node/v18.1.0/bin/npm
npmPackages:
@storybook/addon-actions: next => 7.0.0-alpha.37
@storybook/addon-essentials: next => 7.0.0-alpha.37
@storybook/addon-interactions: next => 7.0.0-alpha.37
@storybook/addon-links: next => 7.0.0-alpha.37
@storybook/addon-svelte-csf: ^2.0.8 => 2.0.8
@storybook/builder-vite: ^0.2.4 => 0.2.4
@storybook/svelte: next => 7.0.0-alpha.37
@storybook/svelte-vite: ^7.0.0-alpha.37 => 7.0.0-alpha.37
@storybook/testing-library: ^0.0.13 => 0.0.13
Ah, yep. @storybook/builder-vite
should be the same alpha version as the rest.
Rookie mistake - I thought I've checked all deps. Clearly not ;) Thanks that works
@IanVS however I keep fighting with issue for a long while - when building storybook, it does not do complete build ( missing iframe.html) and it's the case still. I can't figure it out, build completes but files are missing and it does not work when deployed
Are you deploying in a subdirectory? Maybe you're hitting https://github.com/storybookjs/builder-vite/issues/238? If you want to hop into the #vite channel in https://discord.gg/storybook, I'd be happy to help you troubleshoot.
@benmccann I'm seeing this when trying to build:
The following Vite config options will be overridden by SvelteKit:
- build.emptyOutDir
- build.outDir
- build.rollupOptions.input
- root
Is there a way to prevent sveltekit from overriding those settings?
I guess maybe we'll need to create our own plugin with config
hook that un-overrides them. ๐
Hmmm, but then it still fails because sveltekit looks for certain things in a specific spot...
ENOENT: no such file or directory, open '/Users/ianvs/code/experiments/sveltekit/.svelte-kit/output/client/_app/version.json'
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. 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)
But I assume that we're a pretty niche use case and I can't imagine why anyone other than Storybook would benefit from this, so I can understand if the Svelte team is hesitant to support this kind of thing.
Alternatively, separating the SvelteKit features from from server/build handling into separate sub-vite-plugins so we could disable the necessary plugin manually. Basically the same as above but in a less official way.
Son of a gun!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-alpha.38 containing PR #19338 that references this issue. Upgrade today to the @next
NPM tag to try it out!
npx sb upgrade --prerelease
Closing this issue. Please re-open if you think there's still more to do.
https://github.com/storybookjs/storybook/issues/19280#issuecomment-1277810919 is still a problem (can't build).
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.
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.
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$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.
Son of a gun!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-alpha.41 containing PR #19522 that references this issue. Upgrade today to the @next
NPM tag to try it out!
npx sb upgrade --prerelease
Closing this issue. Please re-open if you think there's still more to do.
When I init and run Storybook 7 with a new SvelteKit project, I get this error on Windows:
[vite] error while updating dependencies:
Error: ENOENT: no such file or directory,
rename 'C:\dev\svelte-storybook7\node_modules\.cache\.vite-storybook\deps_temp'
-> 'C:\dev\svelte-storybook7\node_modules\.cache\.vite-storybook\deps'
The storybook shell will load but each page has no content.
npm create svelte@latest
npm i
npx sb@next init
(I'm running npm 8.17.0
so I agree to the prompt to run the npm7
migration on my project)npm run storybook
Unfortunately that's a vite error: https://github.com/vitejs/vite/issues/9986.
You may be able to get past it by removing the node_modules/.cache
directory, and restarting storybook.
Describe the bug A standard bootstrap of a sveltekit + storybook project fails to start.
To Reproduce
yarn create svelte
skeleton
for the template andno
for everything elseyarn
npx sb@future init
yarn storybook
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#L24But 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