Skip to content

Commit

Permalink
Merge pull request #19978 from storybookjs/vite/prebundle
Browse files Browse the repository at this point in the history
Vite: Fix prebundling
  • Loading branch information
ndelangen authored Nov 28, 2022
2 parents fd1db96 + 3442b18 commit 998868c
Show file tree
Hide file tree
Showing 30 changed files with 145 additions and 526 deletions.
3 changes: 0 additions & 3 deletions code/frameworks/react-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@
"@joshwooding/vite-plugin-react-docgen-typescript": "^0.0.5",
"@rollup/pluginutils": "^4.2.0",
"@storybook/builder-vite": "7.0.0-alpha.54",
"@storybook/channel-postmessage": "7.0.0-alpha.54",
"@storybook/channel-websocket": "7.0.0-alpha.54",
"@storybook/preview-api": "7.0.0-alpha.54",
"@storybook/react": "7.0.0-alpha.54",
"@vitejs/plugin-react": "^2.0.0",
"ast-types": "^0.14.2",
Expand Down
10 changes: 0 additions & 10 deletions code/frameworks/react-vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1 @@
// TODO: figure out if any of this is required
// possibly make it not required, framework should never be imported directly, except for types in config files

export { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage';
export { createChannel as createWebSocketChannel } from '@storybook/channel-websocket';

export { addons } from '@storybook/preview-api';
export { composeConfigs, PreviewWeb } from '@storybook/preview-api';
export { ClientApi } from '@storybook/preview-api';

export type { StorybookConfig } from '@storybook/builder-vite';
3 changes: 0 additions & 3 deletions code/frameworks/svelte-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@
"dependencies": {
"@storybook/addon-svelte-csf": "^2.0.0",
"@storybook/builder-vite": "7.0.0-alpha.54",
"@storybook/channel-postmessage": "7.0.0-alpha.54",
"@storybook/channel-websocket": "7.0.0-alpha.54",
"@storybook/node-logger": "7.0.0-alpha.54",
"@storybook/preview-api": "7.0.0-alpha.54",
"@storybook/svelte": "7.0.0-alpha.54",
"@sveltejs/vite-plugin-svelte": "^1.0.0",
"magic-string": "^0.26.1",
Expand Down
7 changes: 0 additions & 7 deletions code/frameworks/svelte-vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
export { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage';
export { createChannel as createWebSocketChannel } from '@storybook/channel-websocket';

export { addons } from '@storybook/preview-api';
export { composeConfigs, PreviewWeb } from '@storybook/preview-api';
export { ClientApi } from '@storybook/preview-api';

export type { StorybookConfig } from '@storybook/builder-vite';
3 changes: 0 additions & 3 deletions code/frameworks/vue-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@
},
"dependencies": {
"@storybook/builder-vite": "7.0.0-alpha.54",
"@storybook/channel-postmessage": "7.0.0-alpha.54",
"@storybook/channel-websocket": "7.0.0-alpha.54",
"@storybook/core-common": "7.0.0-alpha.54",
"@storybook/core-server": "7.0.0-alpha.54",
"@storybook/preview-api": "7.0.0-alpha.54",
"@storybook/vue": "7.0.0-alpha.54",
"magic-string": "^0.26.1",
"vite": "^3.1.3",
Expand Down
7 changes: 0 additions & 7 deletions code/frameworks/vue-vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
export { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage';
export { createChannel as createWebSocketChannel } from '@storybook/channel-websocket';

export { addons } from '@storybook/preview-api';
export { composeConfigs, PreviewWeb } from '@storybook/preview-api';
export { ClientApi } from '@storybook/preview-api';

export type { StorybookConfig } from '@storybook/builder-vite';
3 changes: 0 additions & 3 deletions code/frameworks/vue3-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@
},
"dependencies": {
"@storybook/builder-vite": "7.0.0-alpha.54",
"@storybook/channel-postmessage": "7.0.0-alpha.54",
"@storybook/channel-websocket": "7.0.0-alpha.54",
"@storybook/core-server": "7.0.0-alpha.54",
"@storybook/preview-api": "7.0.0-alpha.54",
"@storybook/vue3": "7.0.0-alpha.54",
"@vitejs/plugin-vue": "^3.0.0",
"magic-string": "^0.26.1",
Expand Down
7 changes: 0 additions & 7 deletions code/frameworks/vue3-vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
export { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage';
export { createChannel as createWebSocketChannel } from '@storybook/channel-websocket';

export { addons } from '@storybook/preview-api';
export { composeConfigs, PreviewWeb } from '@storybook/preview-api';
export { ClientApi } from '@storybook/preview-api';

export type { StorybookConfig } from '@storybook/builder-vite';
3 changes: 0 additions & 3 deletions code/frameworks/web-components-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,8 @@
},
"dependencies": {
"@storybook/builder-vite": "7.0.0-alpha.54",
"@storybook/channel-postmessage": "7.0.0-alpha.54",
"@storybook/channel-websocket": "7.0.0-alpha.54",
"@storybook/core-server": "7.0.0-alpha.54",
"@storybook/node-logger": "7.0.0-alpha.54",
"@storybook/preview-api": "7.0.0-alpha.54",
"@storybook/web-components": "7.0.0-alpha.54",
"magic-string": "^0.26.1",
"vite": "3"
Expand Down
7 changes: 0 additions & 7 deletions code/frameworks/web-components-vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
export { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage';
export { createChannel as createWebSocketChannel } from '@storybook/channel-websocket';

export { addons } from '@storybook/preview-api';
export { composeConfigs, PreviewWeb } from '@storybook/preview-api';
export { ClientApi } from '@storybook/preview-api';

export type { StorybookConfig } from '@storybook/builder-vite';
8 changes: 2 additions & 6 deletions code/lib/builder-vite/input/iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@
<!-- [BODY HTML SNIPPET HERE] -->
<div id="storybook-root"></div>
<div id="storybook-docs"></div>
<script type="module">
/* eslint-disable import/no-absolute-path, import/extensions, import/no-unresolved */

import '/sb-preview/runtime.mjs';
import '/virtual:/@storybook/builder-vite/vite-app.js';
</script>
<script type="module" src="/sb-preview/runtime.mjs"></script>
<script type="module" src="/virtual:/@storybook/builder-vite/vite-app.js"></script>
</body>
</html>
4 changes: 1 addition & 3 deletions code/lib/builder-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@
"prep": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
"@joshwooding/vite-plugin-react-docgen-typescript": "0.0.5",
"@storybook/addons": "7.0.0-alpha.54",
"@storybook/client-api": "7.0.0-alpha.54",
"@storybook/client-logger": "7.0.0-alpha.54",
"@storybook/core-common": "7.0.0-alpha.54",
"@storybook/mdx2-csf": "next",
Expand All @@ -61,6 +58,7 @@
"glob": "^7.2.0",
"glob-promise": "^4.2.0",
"magic-string": "^0.26.1",
"rollup-plugin-external-globals": "^0.7.1",
"slash": "^3.0.0",
"vite": "^3.1.3"
},
Expand Down
18 changes: 12 additions & 6 deletions code/lib/builder-vite/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { build as viteBuild } from 'vite';
import { build as viteBuild, mergeConfig } from 'vite';
import { commonConfig } from './vite-config';

import type { ExtendedOptions } from './types';
Expand All @@ -8,11 +8,17 @@ export async function build(options: ExtendedOptions) {
const { presets } = options;

const config = await commonConfig(options, 'build');
config.build = {
outDir: options.outputDir,
emptyOutDir: false, // do not clean before running Vite build - Storybook has already added assets in there!
sourcemap: true,
};
config.build = mergeConfig(config, {
build: {
outDir: options.outputDir,
emptyOutDir: false, // do not clean before running Vite build - Storybook has already added assets in there!
sourcemap: true,
rollupOptions: {
// Do not try to bundle the storybook runtime, it is copied into the output dir after the build.
external: ['/sb-preview/runtime.mjs'],
},
},
}).build;

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

Expand Down
9 changes: 4 additions & 5 deletions code/lib/builder-vite/src/codegen-modern-iframe-script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ export async function generateModernIframeScriptCode(options: ExtendedOptions) {
* @todo Inline variable and remove `noinspection`
*/
const code = `
import { ClientApi, composeConfigs, PreviewWeb } from '${frameworkName}';
import '${virtualAddonSetupFile}';
import { importFn } from '${virtualStoriesFile}';
import { composeConfigs, PreviewWeb, ClientApi } from '@storybook/preview-api';
import '${virtualAddonSetupFile}';
import { importFn } from '${virtualStoriesFile}';
const getProjectAnnotations = async () => {
const configs = await Promise.all([${relativePreviewAnnotations
.map((previewAnnotation) => `import('${previewAnnotation}')`)
Expand Down
12 changes: 4 additions & 8 deletions code/lib/builder-vite/src/codegen-set-addon-channel.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { getFrameworkName } from '@storybook/core-common';

import type { ExtendedOptions } from './types';

export async function generateAddonSetupCode(options: ExtendedOptions) {
const framework = await getFrameworkName(options);

export async function generateAddonSetupCode() {
return `
import { createPostMessageChannel, createWebSocketChannel, addons } from '${framework}';
import { createChannel as createPostMessageChannel } from '@storybook/channel-postmessage';
import { createChannel as createWebSocketChannel } from '@storybook/channel-websocket';
import { addons } from '@storybook/preview-api';
const channel = createPostMessageChannel({ page: 'preview' });
addons.setChannel(channel);
Expand Down
10 changes: 1 addition & 9 deletions code/lib/builder-vite/src/optimizeDeps.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as path from 'path';
import { normalizePath, resolveConfig } from 'vite';
import type { InlineConfig as ViteInlineConfig, UserConfig } from 'vite';
import { globalExternals } from '@fal-works/esbuild-plugin-global-externals';
import { definitions } from '@storybook/preview/globals';
import { listStories } from './list-stories';

import type { ExtendedOptions } from './types';
Expand All @@ -15,20 +13,17 @@ const INCLUDE_CANDIDATES = [
'@mdx-js/react',
'@storybook/addon-docs > acorn-jsx',
'@storybook/addon-docs',
'@storybook/preview-api',
'@storybook/channel-postmessage',
'@storybook/channel-websocket',
'@storybook/client-api',
'@storybook/preview-api',
'@storybook/client-logger',
'@storybook/core/client',
'@storybook/types',
'@storybook/preview-api',
'@storybook/preview-api',
'@storybook/preview-web',
'@storybook/react > acorn-jsx',
'@storybook/react',
'@storybook/svelte',
'@storybook/types',
'@storybook/vue3',
'acorn-jsx',
'acorn-walk',
Expand Down Expand Up @@ -124,9 +119,6 @@ export async function getOptimizeDeps(config: ViteInlineConfig, options: Extende
// We need Vite to precompile these dependencies, because they contain non-ESM code that would break
// if we served it directly to the browser.
include,
esbuildOptions: {
plugins: [globalExternals(definitions)],
},
};

return optimizeDeps;
Expand Down
10 changes: 1 addition & 9 deletions code/lib/builder-vite/src/plugins/code-generator-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
if (source === virtualAddonSetupFile) {
return virtualAddonSetupFile;
}
if (source === '/sb-preview/runtime.mjs') {
return '/sb-preview/runtime.mjs';
}

return undefined;
},
Expand All @@ -117,7 +114,7 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
}

if (id === virtualAddonSetupFile) {
return generateAddonSetupCode(options);
return generateAddonSetupCode();
}

if (id === virtualPreviewFile && !storyStoreV7) {
Expand All @@ -131,11 +128,6 @@ export function codeGeneratorPlugin(options: ExtendedOptions): Plugin {
return generateIframeScriptCode(options);
}

// This is handled by the express router, not vite
if (id === '/sb-preview/runtime.mjs') {
return '';
}

if (id === iframeId) {
return fs.readFileSync(
require.resolve('@storybook/builder-vite/input/iframe.html'),
Expand Down
1 change: 1 addition & 0 deletions code/lib/builder-vite/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'rollup-plugin-external-globals';
10 changes: 8 additions & 2 deletions code/lib/builder-vite/src/vite-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import type {
InlineConfig,
} from 'vite';
import viteReact from '@vitejs/plugin-react';
import externalGlobals from 'rollup-plugin-external-globals';
import { isPreservingSymlinks, getFrameworkName } from '@storybook/core-common';
import { globals } from '@storybook/preview/globals';
import {
codeGeneratorPlugin,
injectExportOrderPlugin,
Expand Down Expand Up @@ -38,15 +40,18 @@ export async function commonConfig(
): Promise<ViteInlineConfig> {
const configEnv = _type === 'development' ? configEnvServe : configEnvBuild;

const { config: userConfig = {} } = (await loadConfigFromFile(configEnv)) ?? {};
// 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)) ?? {};

const sbConfig: InlineConfig = {
configFile: false,
cacheDir: 'node_modules/.cache/.vite-storybook',
root: path.resolve(options.configDir, '..'),
// Allow storybook deployed as subfolder. See https://github.com/storybookjs/builder-vite/issues/238
base: './',

plugins: await pluginConfig(options),
resolve: {
preserveSymlinks: isPreservingSymlinks(),
Expand Down Expand Up @@ -86,6 +91,7 @@ export async function pluginConfig(options: ExtendedOptions) {
}
},
},
externalGlobals(globals),
] as PluginOption[];

// We need the react plugin here to support MDX in non-react projects.
Expand Down
23 changes: 2 additions & 21 deletions code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import VirtualModulePlugin from 'webpack-virtual-modules';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';

import type { Options, CoreConfig, DocsOptions, PreviewAnnotation } from '@storybook/types';
import { globals } from '@storybook/preview/globals';
import {
getRendererName,
stringifyProcessEnvs,
Expand Down Expand Up @@ -207,27 +208,7 @@ export default async (
watchOptions: {
ignored: /node_modules/,
},
externals: {
...[
// these packages are pre-bundled, so they are mapped to global shims
// at some point this should only be a single package: preview-api
'addons',
'channel-postmessage',
'channel-websocket',
'channels',
'client-logger',
'core-events',
'preview-api',
].reduce(
(acc, sbPackage) => ({
...acc,
[`@storybook/${sbPackage}`]: `__STORYBOOK_MODULE_${sbPackage
.toUpperCase()
.replaceAll('-', '_')}__`,
}),
{}
),
},
externals: globals,
ignoreWarnings: [
{
message: /export '\S+' was not found in 'global'/,
Expand Down
15 changes: 11 additions & 4 deletions code/lib/cli/src/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ interface LinkOptions {
export const link = async ({ target, local, start }: LinkOptions) => {
const storybookDir = process.cwd();
try {
const packageJson = JSON.parse(fse.readFileSync('package.json', 'utf8'));
if (packageJson.name !== '@storybook/root') throw new Error();
const packageJson = await fse.readJSON('package.json');
if (packageJson.name !== '@storybook/root') {
throw new Error();
}
} catch {
throw new Error('Expected to run link from the root of the storybook monorepo');
}
Expand All @@ -25,7 +27,7 @@ export const link = async ({ target, local, start }: LinkOptions) => {
if (!local) {
const reprosDir = path.join(storybookDir, '../storybook-repros');
logger.info(`Ensuring directory ${reprosDir}`);
fse.ensureDirSync(reprosDir);
await fse.ensureDir(reprosDir);

logger.info(`Cloning ${target}`);
await exec(`git clone ${target}`, { cwd: reprosDir });
Expand All @@ -34,6 +36,8 @@ export const link = async ({ target, local, start }: LinkOptions) => {
reproDir = path.join(reprosDir, reproName);
}

const reproPackageJson = await fse.readJSON(path.join(reproDir, 'package.json'));

const version = spawnSync('yarn', ['--version'], {
cwd: reproDir,
stdio: 'pipe',
Expand All @@ -58,7 +62,10 @@ export const link = async ({ target, local, start }: LinkOptions) => {
logger.info(
`Magic stuff related to @storybook/preset-create-react-app, we need to fix peerDependencies`
);
await exec(`yarn add -D webpack-hot-middleware`, { cwd: reproDir });

if (!reproPackageJson.devDependencies.vite) {
await exec(`yarn add -D webpack-hot-middleware`, { cwd: reproDir });
}

// ensure that linking is possible
await exec(`yarn add @types/node@16`, { cwd: reproDir });
Expand Down
Loading

0 comments on commit 998868c

Please sign in to comment.