import type { StorybookConfig } from '@storybook/nextjs-vite'; import type { Plugin } from 'vite'; /** * Vite plugin that provides an empty stub module for server-only packages * (Payload CMS and its plugins) so they don't get bundled into * the browser build and cause Node.js built-in errors. * * Uses a Proxy-based default export so any named or nested import * resolves to a no-op function at runtime without needing to enumerate * every export. */ function mockServerModules(): Plugin { const serverPrefixes = ['payload', '@payloadcms/']; const resolvedId = '\0mock-server-module'; return { name: 'mock-server-modules', enforce: 'pre', resolveId(source) { if ( serverPrefixes.some( (prefix) => source === prefix || source.startsWith(prefix + '/'), ) ) { return { id: resolvedId, syntheticNamedExports: true }; } return null; }, load(id) { if (id === resolvedId) { return `export default new Proxy({}, { get: (_, p) => p === '__esModule' ? true : () => {} });`; } return null; }, }; } const config: StorybookConfig = { "stories": [ "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)" ], "addons": [], "framework": "@storybook/nextjs-vite", async viteFinal(config) { return { ...config, plugins: [...(config.plugins || []), mockServerModules()], optimizeDeps: { ...config.optimizeDeps, exclude: [ ...(config.optimizeDeps?.exclude || []), 'payload', '@payloadcms/richtext-lexical', '@payloadcms/db-postgres', '@payloadcms/storage-gcs', '@payloadcms/plugin-seo', ], }, css: { preprocessorOptions: { scss: { // This tells Sass to look in the root directory for imports loadPaths: ["./"], }, }, }, }; }, }; export default config;