mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-16 05:03:11 +08:00
Vite: Allow specifying path to vite.config file (#20681)
Issue: #20552 ## What I did I added a new builder option for the Vite builder named `viteConfigPath`, which is a path to a custom config relative to the cwd. If the path does not resolve, a clear error will be thrown with the absolute path being checked. I also added a new utility, `getBuilderOptions()`, which is helpful because these options can be specified two different ways, with `core.builder.options` or `framework.options.builder`. The utility gives an easy way to check both. It gives preference to ~`core.builder.options`~ `framework.options.builder`, since that's the newer way to define the options. ## How to test 1. `yarn task --task sandbox --start-from auto --template react-vite/default-ts` 2. Move the `vite.config.ts` file into `.storybook` 3. Add an alias, like: ```ts export default defineConfig({ plugins: [react()], resolve: { alias: { stories: path.resolve(__dirname, '../src/stories'), }, }, }); ``` 4. Change one of the stories to use this alias, such as the Button story: ```ts import { Button } from 'stories/Button'; ``` 5. Start Storybook, it will fail 6. Add `viteConfigPath: ".storybook/vite.config.ts"` to the builder options in `.storybook/main.ts` 7. Restart storybook, and it should work. ## Checklist <!-- Please check (put an "x" inside the "[ ]") the applicable items below to make sure your PR is ready to be reviewed. --> - [ ] Make sure your changes are tested (stories and/or unit, integration, or end-to-end tests) - [X] Make sure to add/update documentation regarding your changes - [ ] If you are deprecating/removing a feature, make sure to update [MIGRATION.MD](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md) Is there a way to create an automated test for this? I couldn't think of a good way to do it. #### Maintainers - [ ] If this PR should be tested against many or all sandboxes, make sure to add the `ci:merged` or `ci:daily` GH label to it. - [X] Make sure this PR contains **one** of the labels below. `["cleanup", "BREAKING CHANGE", "feature request", "bug", "documentation", "maintenance", "dependencies", "other"]` <!-- Everybody: Please submit all PRs to the `next` branch unless they are specific to the current release. Storybook maintainers cherry-pick bug and documentation fixes into the `main` branch as part of the release process, so you shouldn't need to worry about this. For additional guidance: https://storybook.js.org/docs/react/contribute/how-to-contribute -->
This commit is contained in:
commit
994a26df8f
@ -66,8 +66,26 @@ For other details about the differences between vite and webpack projects, be su
|
||||
### Customize Vite config
|
||||
|
||||
The builder _will_ read your `vite.config.js` file, though it may change some of the options in order to work correctly.
|
||||
It looks for the Vite config in the CWD. If your config is located elsewhere, specify the path using the `viteConfigPath` builder option:
|
||||
|
||||
In `.storybook/main.js` (or whatever your Storybook config file is named), you can override the merged Vite config:
|
||||
```javascript
|
||||
// .storybook/main.mjs
|
||||
|
||||
const config = {
|
||||
framework: {
|
||||
name: '@storybook/react-vite', // Your framework name here.
|
||||
options: {
|
||||
builder: {
|
||||
viteConfigPath: '.storybook/customViteConfig.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
```
|
||||
|
||||
You can also override the merged Vite config:
|
||||
|
||||
```javascript
|
||||
// use `mergeConfig` to recursively merge Vite options
|
||||
|
@ -17,4 +17,9 @@ export type StorybookConfigVite = {
|
||||
viteFinal?: ViteFinal;
|
||||
};
|
||||
|
||||
export type BuilderOptions = {};
|
||||
export type BuilderOptions = {
|
||||
/**
|
||||
* Path to vite.config file, relative to CWD.
|
||||
*/
|
||||
viteConfigPath?: string;
|
||||
};
|
||||
|
@ -8,7 +8,7 @@ import type {
|
||||
InlineConfig,
|
||||
} from 'vite';
|
||||
import { viteExternalsPlugin } from 'vite-plugin-externals';
|
||||
import { isPreservingSymlinks, getFrameworkName } from '@storybook/core-common';
|
||||
import { isPreservingSymlinks, getFrameworkName, getBuilderOptions } from '@storybook/core-common';
|
||||
import { globals } from '@storybook/preview/globals';
|
||||
import type { Options } from '@storybook/types';
|
||||
import {
|
||||
@ -18,6 +18,7 @@ import {
|
||||
mdxPlugin,
|
||||
stripStoryHMRBoundary,
|
||||
} from './plugins';
|
||||
import type { BuilderOptions } from './types';
|
||||
|
||||
export type PluginConfigType = 'build' | 'development';
|
||||
|
||||
@ -39,12 +40,13 @@ export async function commonConfig(
|
||||
_type: PluginConfigType
|
||||
): Promise<ViteInlineConfig> {
|
||||
const configEnv = _type === 'development' ? configEnvServe : configEnvBuild;
|
||||
const { viteConfigPath } = await getBuilderOptions<BuilderOptions>(options);
|
||||
|
||||
// I destructure away the `build` property from the user's config object
|
||||
// I do this because I can contain config that breaks storybook, such as we had in a lit project.
|
||||
// If the user needs to configure the `build` they need to do so in the viteFinal function in main.js.
|
||||
const { config: { build: buildProperty = undefined, ...userConfig } = {} } =
|
||||
(await loadConfigFromFile(configEnv)) ?? {};
|
||||
(await loadConfigFromFile(configEnv, viteConfigPath)) ?? {};
|
||||
|
||||
const sbConfig: InlineConfig = {
|
||||
configFile: false,
|
||||
|
@ -6,6 +6,7 @@ export * from './utils/cache';
|
||||
export * from './utils/check-addon-order';
|
||||
export * from './utils/envs';
|
||||
export * from './utils/findDistEsm';
|
||||
export * from './utils/get-builder-options';
|
||||
export * from './utils/get-framework-name';
|
||||
export * from './utils/get-renderer-name';
|
||||
export * from './utils/get-storybook-configuration';
|
||||
|
23
code/lib/core-common/src/utils/get-builder-options.ts
Normal file
23
code/lib/core-common/src/utils/get-builder-options.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import type { Options } from '@storybook/types';
|
||||
|
||||
/**
|
||||
* Builder options can be specified in `core.builder.options` or `framework.options.builder`.
|
||||
* Preference is given here to `framework.options.builder` if both are specified.
|
||||
*/
|
||||
export async function getBuilderOptions<T extends Record<string, any>>(
|
||||
options: Options
|
||||
): Promise<T | Record<string, never>> {
|
||||
const framework = await options.presets.apply('framework', {}, options);
|
||||
|
||||
if (typeof framework !== 'string' && framework?.options?.builder) {
|
||||
return framework.options.builder;
|
||||
}
|
||||
|
||||
const { builder } = await options.presets.apply('core', {}, options);
|
||||
|
||||
if (typeof builder !== 'string' && builder?.options) {
|
||||
return builder.options as T;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user