-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Vite: Add partial SvelteKit support #19338
Changes from 8 commits
70f36b4
7d4c117
ceaf69b
41091a6
f205c1c
314d985
6056660
8d38821
0a7f052
bb3583a
22ff5e7
ea50752
5a53bca
fef7850
ab91bc8
c2ccb55
5deb296
7ecab8d
26a2614
da547d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import type { StorybookConfig } from '@storybook/builder-vite'; | ||
import { PluginOption } from 'vite'; | ||
import { svelteDocgen } from './plugins/svelte-docgen'; | ||
|
||
export const addons: StorybookConfig['addons'] = ['@storybook/svelte']; | ||
|
@@ -12,8 +13,23 @@ export const viteFinal: StorybookConfig['viteFinal'] = async (config, { presets | |
|
||
plugins.push(svelteDocgen(config)); | ||
|
||
removeSvelteKitPlugin(plugins); | ||
|
||
return { | ||
...config, | ||
plugins, | ||
}; | ||
}; | ||
|
||
const removeSvelteKitPlugin = (plugins: PluginOption[]) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd still love to find a way to avoid having to do this, since we'll start getting complaints about sveltekit aliases not working (even though there seems to be some debate over whether they should be used at all inside components). But, this seems like a reasonable workaround for now, until we can figure it out. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, let's continue investigating the core issue and do a follow up to this. |
||
plugins.forEach((plugin, index) => { | ||
if (plugin && 'name' in plugin && plugin.name === 'vite-plugin-svelte-kit') { | ||
// eslint-disable-next-line no-param-reassign -- we explicitly want to mutate the array as stated here: https://vitejs.dev/guide/api-plugin.html#config | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is not in a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Vite docs are a bit unclear on how it's handled when a partial config is returned - they say it is deeply merged into the existing config, which led me to believe it's not usable for removing any entries as we want to achieve here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but those docs are for a plugin. This code is not inside a plugin, it's directly modifying the config that we'll end up passing to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh yeah, I hadn't even noticed that. export const viteFinal: StorybookConfig['viteFinal'] = async (config, { presets }) => {
const { plugins = [] } = config;
return {
...config,
plugins: [
// remove SvelteKit plugin
...plugins.map(withoutSvelteKitPlugin),
// Add svelte plugin if not present
!hasPlugin(plugins, 'vite-plugin-svelte') &&
(await import('@sveltejs/vite-plugin-svelte')).svelte(),
// Add docgen plugin
svelteDocgen(config),
].filter(Boolean),
};
};
const withoutSvelteKitPlugin = (plugin: PluginOption): PluginOption => {
if (Array.isArray(plugin)) {
// recursive - Vite plugins can be nested
return plugin.map(withoutSvelteKitPlugin).filter(Boolean);
}
if (plugin && 'name' in plugin && plugin.name === 'vite-plugin-svelte-kit') {
return undefined;
}
return plugin;
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, the way you've got it right now is fine I think, and hopefully this is temporary anyway, until we can figure out what's causing the app to load instead of storybook in 7.0. |
||
plugins[index] = undefined; | ||
} | ||
if (Array.isArray(plugin)) { | ||
// recursive, Vite plugins can be nested | ||
removeSvelteKitPlugin(plugin); | ||
} | ||
}); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,13 @@ | ||
import fse from 'fs-extra'; | ||
import { logger } from '@storybook/node-logger'; | ||
|
||
import { CoreBuilder } from '../../project_types'; | ||
import { baseGenerator } from '../baseGenerator'; | ||
import { Generator } from '../types'; | ||
|
||
const generator: Generator = async (packageManager, npmOptions, options) => { | ||
let extraMain; | ||
// svelte.config.js ? | ||
if (fse.existsSync('./svelte.config.js')) { | ||
logger.info("Configuring preprocessor from 'svelte.config.js'"); | ||
|
||
extraMain = { | ||
svelteOptions: { preprocess: '%%require("../svelte.config.js").preprocess%%' }, | ||
}; | ||
} else if (fse.existsSync('./svelte.config.cjs')) { | ||
logger.info("Configuring preprocessor from 'svelte.config.cjs'"); | ||
|
||
extraMain = { | ||
svelteOptions: { preprocess: '%%require("../svelte.config.cjs").preprocess%%' }, | ||
}; | ||
} else { | ||
// svelte-preprocess dependencies ? | ||
const packageJson = packageManager.retrievePackageJson(); | ||
if (packageJson.devDependencies && packageJson.devDependencies['svelte-preprocess']) { | ||
logger.info("Configuring preprocessor with 'svelte-preprocess'"); | ||
|
||
extraMain = { | ||
svelteOptions: { preprocess: '%%require("svelte-preprocess")()%%' }, | ||
}; | ||
} | ||
} | ||
|
||
Comment on lines
-9
to
-34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as per #19280 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need any MIGRATION.md notes? @JReinhold There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, users needs to remove their I'll write it up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about pulling this change out to its own PR? I'd love to get it into the next release, since svelte apps are currently broken after bootstrapping with Storybook. |
||
const extraPackages = options.builder === CoreBuilder.Webpack5 ? ['svelte', 'svelte-loader'] : []; | ||
|
||
await baseGenerator(packageManager, npmOptions, options, 'svelte', { | ||
extraPackages, | ||
extensions: ['js', 'jsx', 'ts', 'tsx', 'svelte'], | ||
extraMain, | ||
commonJs: true, | ||
}); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import { | |
import prompts from 'prompts'; | ||
import type { AbortController } from 'node-abort-controller'; | ||
import command from 'execa'; | ||
import dedent from 'ts-dedent'; | ||
|
||
import { createOptions, getOptionsOrPrompt, OptionValues } from './utils/options'; | ||
import { executeCLIStep } from './utils/cli-step'; | ||
|
@@ -245,16 +246,31 @@ function addEsbuildLoaderToStories(mainConfig: ConfigFile) { | |
); | ||
} | ||
|
||
// Recompile optimized deps on each startup, so you can change @storybook/* packages and not | ||
// have to clear caches. | ||
function forceViteRebuilds(mainConfig: ConfigFile) { | ||
/* | ||
Recompile optimized deps on each startup, so you can change @storybook/* packages and not | ||
have to clear caches. | ||
And allow "template-stories" directory if necessary | ||
|
||
*/ | ||
function setSandboxViteFinal(mainConfig: ConfigFile) { | ||
const viteFinalCode = ` | ||
(config) => ({ | ||
...config, | ||
optimizeDeps: { | ||
...config.optimizeDeps, | ||
force: true, | ||
}, | ||
plugins: [ | ||
...config.plugins, | ||
{ | ||
name: 'storybook:allow-template-stories', | ||
config(config) { | ||
if (config?.server?.fs?.allow) { | ||
config.server.fs.allow.push('template-stories'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you could also just set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah I tried that but you actually can't because that won't pick up on other plugin's configs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant without the check, you could just set the allow value directly, and then the rest of everything should still work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm I don't think that I understand what you're saying, so bear with me. My (verbose explanation of my) logic is:
Which part of the above sounds wrong to you? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the plugin is probably the safer approach because it can check whether the user has set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this sandbox, we are the user. I'm not talking about setting it in all cases, just in the example sandbox, which is used for testing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh yeah, that sounds like the better approach then There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah right, gotcha. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've allowed |
||
} | ||
}, | ||
}, | ||
], | ||
})`; | ||
mainConfig.setFieldNode( | ||
['viteFinal'], | ||
|
@@ -467,7 +483,7 @@ export async function sandbox(optionValues: OptionValues<typeof options>) { | |
// Add some extra settings (see above for what these do) | ||
mainConfig.setFieldValue(['core', 'disableTelemetry'], true); | ||
if (builder === '@storybook/builder-webpack5') addEsbuildLoaderToStories(mainConfig); | ||
if (builder === '@storybook/builder-vite') forceViteRebuilds(mainConfig); | ||
if (builder === '@storybook/builder-vite') setSandboxViteFinal(mainConfig); | ||
|
||
await writeConfig(mainConfig); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this should have been a plugin, but it doesn't seem to have an affect. The plugin correctly removes
vite-plugin-svelte-kit
from the config but it doesn't change any behaviorThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes unfortunately there's no way to remove plugins from within a plugin, as far as I can tell.