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

Vite: Support Vite 5 #24395

Merged
merged 20 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/builders/builder-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"peerDependencies": {
"@preact/preset-vite": "*",
"typescript": ">= 4.3.x",
"vite": "^3.0.0 || ^4.0.0",
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0",
"vite-plugin-glimmerx": "*"
},
"peerDependenciesMeta": {
Expand Down
3 changes: 1 addition & 2 deletions code/builders/builder-vite/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { build as viteBuild, mergeConfig } from 'vite';
import type { Options } from '@storybook/types';
import { commonConfig } from './vite-config';

import { sanitizeEnvVars } from './envs';

export async function build(options: Options) {
const { build: viteBuild, mergeConfig } = await import('vite');
const { presets } = options;

const config = await commonConfig(options, 'build');
Expand All @@ -21,6 +21,5 @@ export async function build(options: Options) {
}).build;

const finalConfig = await presets.apply('viteFinal', config, options);

await viteBuild(await sanitizeEnvVars(options, finalConfig));
}
10 changes: 7 additions & 3 deletions code/builders/builder-vite/src/codegen-entries.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { loadPreviewOrConfigFile } from '@storybook/core-common';
import type { Options } from '@storybook/types';
import slash from 'slash';
import { normalizePath } from 'vite';
import { listStories } from './list-stories';

const absoluteFilesToImport = (files: string[], name: string) =>
const absoluteFilesToImport = async (
files: string[],
name: string,
normalizePath: (id: string) => string
) =>
files
.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'/@fs/${normalizePath(el)}'`)
.join('\n');

export async function generateVirtualStoryEntryCode(options: Options) {
const { normalizePath } = await import('vite');
const storyEntries = await listStories(options);
const resolveMap = storyEntries.reduce<Record<string, string>>(
(prev, entry) => ({ ...prev, [entry]: entry.replace(slash(process.cwd()), '.') }),
Expand All @@ -18,7 +22,7 @@ export async function generateVirtualStoryEntryCode(options: Options) {
const modules = storyEntries.map((entry, i) => `${JSON.stringify(entry)}: story_${i}`).join(',');

return `
${absoluteFilesToImport(storyEntries, 'story')}
${await absoluteFilesToImport(storyEntries, 'story', normalizePath)}

function loadable(key) {
return {${modules}}[key];
Expand Down
3 changes: 2 additions & 1 deletion code/builders/builder-vite/src/codegen-importfn-script.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as path from 'path';
import { normalizePath } from 'vite';

import type { Options } from '@storybook/types';
import { logger } from '@storybook/node-logger';

Expand All @@ -26,6 +26,7 @@ function toImportPath(relativePath: string) {
* @param stories An array of absolute story paths.
*/
async function toImportFn(stories: string[]) {
const { normalizePath } = await import('vite');
const objectEntries = stories.map((file) => {
const ext = path.extname(file);
const relativePath = normalizePath(path.relative(process.cwd(), file));
Expand Down
3 changes: 2 additions & 1 deletion code/builders/builder-vite/src/list-stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { glob } from 'glob';
import { normalizeStories, commonGlobOptions } from '@storybook/core-common';

import type { Options } from '@storybook/types';
import { normalizePath } from 'vite';

export async function listStories(options: Options) {
const { normalizePath } = await import('vite');

return (
await Promise.all(
normalizeStories(await options.presets.apply('stories', [], options), {
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-vite/src/optimizeDeps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as path from 'path';
import { normalizePath, resolveConfig } from 'vite';
import type { InlineConfig as ViteInlineConfig, UserConfig } from 'vite';
import type { Options } from '@storybook/types';
import { listStories } from './list-stories';
Expand Down Expand Up @@ -128,6 +127,7 @@ const asyncFilter = async (arr: string[], predicate: (val: string) => Promise<bo

export async function getOptimizeDeps(config: ViteInlineConfig, options: Options) {
const { root = process.cwd() } = config;
const { normalizePath, resolveConfig } = await import('vite');
const absoluteStories = await listStories(options);
const stories = absoluteStories.map((storyPath) => normalizePath(path.relative(root, storyPath)));
// TODO: check if resolveConfig takes a lot of time, possible optimizations here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import findCacheDirectory from 'find-cache-dir';
import { init, parse } from 'es-module-lexer';
import MagicString from 'magic-string';
import { ensureFile, writeFile } from 'fs-extra';
import { mergeAlias } from 'vite';
import type { Alias, Plugin } from 'vite';

const escapeKeys = (key: string) => key.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
Expand Down Expand Up @@ -38,6 +37,8 @@ const replacementMap = new Map([
*/
export async function externalGlobalsPlugin(externals: Record<string, string>) {
await init;
const { mergeAlias } = await import('vite');

return {
name: 'storybook:external-globals-plugin',
enforce: 'post',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
import { parse } from 'es-module-lexer';
import MagicString from 'magic-string';
import { createFilter } from 'vite';

const include = [/\.stories\.([tj])sx?$/, /(stories|story).mdx$/];
const filter = createFilter(include);
export async function injectExportOrderPlugin() {
const { createFilter } = await import('vite');

export const injectExportOrderPlugin = {
name: 'storybook:inject-export-order-plugin',
// This should only run after the typescript has been transpiled
enforce: 'post',
async transform(code: string, id: string) {
if (!filter(id)) return undefined;
const include = [/\.stories\.([tj])sx?$/, /(stories|story).mdx$/];
const filter = createFilter(include);

// TODO: Maybe convert `injectExportOrderPlugin` to function that returns object,
// and run `await init;` once and then call `parse()` without `await`,
// instead of calling `await parse()` every time.
const [, exports] = await parse(code);
return {
name: 'storybook:inject-export-order-plugin',
// This should only run after the typescript has been transpiled
enforce: 'post',
async transform(code: string, id: string) {
if (!filter(id)) return undefined;

if (exports.includes('__namedExportsOrder')) {
// user has defined named exports already
return undefined;
}
const s = new MagicString(code);
const orderedExports = exports.filter((e) => e !== 'default');
s.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`);
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
},
};
// TODO: Maybe convert `injectExportOrderPlugin` to function that returns object,
// and run `await init;` once and then call `parse()` without `await`,
// instead of calling `await parse()` every time.
const [, exports] = await parse(code);

if (exports.includes('__namedExportsOrder')) {
// user has defined named exports already
return undefined;
}
const s = new MagicString(code);
const orderedExports = exports.filter((e) => e !== 'default');
s.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`);
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
},
};
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { Plugin } from 'vite';
import { createFilter } from 'vite';
import MagicString from 'magic-string';

/**
* This plugin removes HMR `accept` calls in story files. Stories should not be treated
* as hmr boundaries, but vite has a bug which causes them to be treated as boundaries
* (https://github.com/vitejs/vite/issues/9869).
*/
export function stripStoryHMRBoundary(): Plugin {
export async function stripStoryHMRBoundary(): Promise<Plugin> {
const { createFilter } = await import('vite');

const filter = createFilter(/\.stories\.([tj])sx?$/);
return {
name: 'storybook:strip-hmr-boundary-plugin',
Expand Down
7 changes: 4 additions & 3 deletions code/builders/builder-vite/src/vite-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as path from 'path';
import { loadConfigFromFile, mergeConfig } from 'vite';
import findCacheDirectory from 'find-cache-dir';
import type {
ConfigEnv,
Expand Down Expand Up @@ -41,6 +40,8 @@ export async function commonConfig(
_type: PluginConfigType
): Promise<ViteInlineConfig> {
const configEnv = _type === 'development' ? configEnvServe : configEnvBuild;
const { loadConfigFromFile, mergeConfig } = await import('vite');

const { viteConfigPath } = await getBuilderOptions<BuilderOptions>(options);

const projectRoot = path.resolve(options.configDir, '..');
Expand Down Expand Up @@ -80,8 +81,8 @@ export async function pluginConfig(options: Options) {
const plugins = [
codeGeneratorPlugin(options),
await csfPlugin(options),
injectExportOrderPlugin,
stripStoryHMRBoundary(),
await injectExportOrderPlugin(),
await stripStoryHMRBoundary(),
{
name: 'storybook:allow-storybook-dir',
enforce: 'post',
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-vite/src/vite-server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Server } from 'http';
import { createServer } from 'vite';
import type { Options } from '@storybook/types';
import { commonConfig } from './vite-config';
import { getOptimizeDeps } from './optimizeDeps';
Expand Down Expand Up @@ -29,5 +28,6 @@ export async function createViteServer(options: Options, devServer: Server) {

const finalConfig = await presets.apply('viteFinal', config, options);

const { createServer } = await import('vite');
return createServer(await sanitizeEnvVars(options, finalConfig));
}
2 changes: 1 addition & 1 deletion code/frameworks/preact-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
},
"peerDependencies": {
"preact": ">=10",
"vite": "^3.0.0 || ^4.0.0"
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"engines": {
"node": ">=16"
Expand Down
4 changes: 2 additions & 2 deletions code/frameworks/react-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"prep": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@joshwooding/vite-plugin-react-docgen-typescript": "0.2.1",
"@joshwooding/vite-plugin-react-docgen-typescript": "0.3.0",
IanVS marked this conversation as resolved.
Show resolved Hide resolved
"@rollup/pluginutils": "^5.0.2",
"@storybook/builder-vite": "workspace:*",
"@storybook/react": "workspace:*",
Expand All @@ -63,7 +63,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
"vite": "^3.0.0 || ^4.0.0"
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"engines": {
"node": ">=16"
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/svelte-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
},
"peerDependencies": {
"svelte": "^3.0.0 || ^4.0.0",
"vite": "^3.0.0 || ^4.0.0"
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"engines": {
"node": "^14.18 || >=16"
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/vue-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
"vite": "^3.0.0 || ^4.0.0",
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0",
"vue": "^2.7.0"
},
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/vue3-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
"vite": "^3.0.0 || ^4.0.0"
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"engines": {
"node": "^14.18 || >=16"
Expand Down
24 changes: 12 additions & 12 deletions code/lib/cli/src/sandbox-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const baseTemplates = {
},
'react-vite/default-js': {
name: 'React Latest (Vite | JavaScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template react',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template react',
expected: {
framework: '@storybook/react-vite',
renderer: '@storybook/react',
Expand All @@ -149,7 +149,7 @@ const baseTemplates = {
},
'react-vite/default-ts': {
name: 'React Latest (Vite | TypeScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template react-ts',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template react-ts',
expected: {
framework: '@storybook/react-vite',
renderer: '@storybook/react',
Expand Down Expand Up @@ -204,7 +204,7 @@ const baseTemplates = {
},
'vue3-vite/default-js': {
name: 'Vue v3 (Vite | JavaScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template vue',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template vue',
expected: {
framework: '@storybook/vue3-vite',
renderer: '@storybook/vue3',
Expand All @@ -214,7 +214,7 @@ const baseTemplates = {
},
'vue3-vite/default-ts': {
name: 'Vue v3 (Vite | TypeScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template vue-ts',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template vue-ts',
expected: {
framework: '@storybook/vue3-vite',
renderer: '@storybook/vue3',
Expand Down Expand Up @@ -246,7 +246,7 @@ const baseTemplates = {
'html-vite/default-js': {
name: 'HTML Latest (Vite | JavaScript)',
script:
'npm create vite@latest --yes {{beforeDir}} -- --template vanilla && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
'npm create vite@beta --yes {{beforeDir}} -- --template vanilla && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
expected: {
framework: '@storybook/html-vite',
renderer: '@storybook/html',
Expand All @@ -257,7 +257,7 @@ const baseTemplates = {
'html-vite/default-ts': {
name: 'HTML Latest (Vite | TypeScript)',
script:
'npm create vite@latest --yes {{beforeDir}} -- --template vanilla-ts && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
'npm create vite@beta --yes {{beforeDir}} -- --template vanilla-ts && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
expected: {
framework: '@storybook/html-vite',
renderer: '@storybook/html',
Expand All @@ -267,7 +267,7 @@ const baseTemplates = {
},
'svelte-vite/default-js': {
name: 'Svelte Latest (Vite | JavaScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template svelte',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template svelte',
expected: {
framework: '@storybook/svelte-vite',
renderer: '@storybook/svelte',
Expand All @@ -277,7 +277,7 @@ const baseTemplates = {
},
'svelte-vite/default-ts': {
name: 'Svelte Latest (Vite | TypeScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template svelte-ts',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template svelte-ts',
expected: {
framework: '@storybook/svelte-vite',
renderer: '@storybook/svelte',
Expand Down Expand Up @@ -346,7 +346,7 @@ const baseTemplates = {
'lit-vite/default-js': {
name: 'Lit Latest (Vite | JavaScript)',
script:
'npm create vite@latest --yes {{beforeDir}} -- --template lit && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
'npm create vite@beta --yes {{beforeDir}} -- --template lit && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
expected: {
framework: '@storybook/web-components-vite',
renderer: '@storybook/web-components',
Expand All @@ -358,7 +358,7 @@ const baseTemplates = {
'lit-vite/default-ts': {
name: 'Lit Latest (Vite | TypeScript)',
script:
'npm create vite@latest --yes {{beforeDir}} -- --template lit-ts && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
'npm create vite@beta --yes {{beforeDir}} -- --template lit-ts && cd {{beforeDir}} && echo "export default {}" > vite.config.js',
ndelangen marked this conversation as resolved.
Show resolved Hide resolved
expected: {
framework: '@storybook/web-components-vite',
renderer: '@storybook/web-components',
Expand Down Expand Up @@ -415,7 +415,7 @@ const baseTemplates = {
},
'preact-vite/default-js': {
name: 'Preact Latest (Vite | JavaScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template preact',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template preact',
expected: {
framework: '@storybook/preact-vite',
renderer: '@storybook/preact',
Expand All @@ -425,7 +425,7 @@ const baseTemplates = {
},
'preact-vite/default-ts': {
name: 'Preact Latest (Vite | TypeScript)',
script: 'npm create vite@latest --yes {{beforeDir}} -- --template preact-ts',
script: 'npm create vite@beta --yes {{beforeDir}} -- --template preact-ts',
expected: {
framework: '@storybook/preact-vite',
renderer: '@storybook/preact',
Expand Down
Loading