UNPKG

vite-plugin-react-server

Version:
123 lines (109 loc) 4 kB
import type { OutputBundle, PluginContext, OutputChunk, } from "rollup"; import { createInputNormalizer } from "./inputNormalizer.js"; import { DEFAULT_CONFIG } from "../config/index.js"; interface BundleManifestEntry { file: string; name: string; src?: string; isEntry?: boolean; imports?: string[]; dynamicImports?: string[]; css?: string[]; } /** * Get the bundle manifest from the plugin context. Will only work during production build * @param pluginContext - The plugin context * @param bundle - The bundle * @param preserveModulesRoot - The preserve modules root * @returns The bundle manifest */ export function getBundleManifest({ pluginContext, bundle, moduleBase, preserveModulesRoot, }: { pluginContext: PluginContext, bundle: OutputBundle, moduleBase?: string, preserveModulesRoot?: boolean, }): Record<string, BundleManifestEntry> { const normalizer = createInputNormalizer({ root: pluginContext.environment.config.root, removeExtension: DEFAULT_CONFIG.FILE_REGEX, preserveModulesRoot: preserveModulesRoot === true ? moduleBase : undefined, }); if (!bundle) return {}; // Track virtual modules to prevent duplicates const virtualModules = new Map<string, string>(); const bundleManifest = Object.fromEntries( Object.entries(bundle) .map(([fileName, chunk]) => { if (chunk.type !== "chunk") return null as never; const chunkWithFacade = chunk as OutputChunk; // Get the module ID, preferring facadeModuleId const moduleId = chunkWithFacade.facadeModuleId || chunkWithFacade.moduleIds[0] || fileName; // Handle commonjs helpers specially - must be done before normalization if (moduleId.includes('commonjsHelpers')) { return [ moduleId, { file: 'commonjs-runtime.js', name: 'commonjsHelpers', src: moduleId, isEntry: false } ]; } // Normalize both paths, removing the root prefix let [normalizedId, sourcePath] = normalizer(moduleId); // For virtual modules, use a consistent naming scheme let finalFileName = fileName; if (moduleId.includes('?')) { const [basePath, query] = moduleId.split('?'); const virtualPath = basePath.includes('node_modules') ? basePath.split('node_modules/')[1] : basePath; // Create a unique key for this virtual module const virtualKey = `${virtualPath}?${query}`; if (!virtualModules.has(virtualKey)) { // First time seeing this virtual module const virtualFileName = `${virtualPath.replace(/\.js$/, '')}.${query}.js`; virtualModules.set(virtualKey, virtualFileName); } finalFileName = virtualModules.get(virtualKey)!; } // handle preserveModulesRoot if(normalizedId.startsWith('\x00')){ normalizedId = normalizedId.slice(1); } if(sourcePath.startsWith('/')){ sourcePath = sourcePath.slice(1); } if(moduleBase && preserveModulesRoot && normalizedId?.startsWith(moduleBase + '/')) { normalizedId = normalizedId.slice(moduleBase.length + 1); } const bundleManifestEntry = [ sourcePath, { file: finalFileName, name: normalizedId, src: sourcePath, isEntry: chunk.isEntry, ...(chunk.imports?.length > 0 ? { imports: chunk.imports } : {}), ...(chunk.dynamicImports?.length > 0 ? { dynamicImports: chunk.dynamicImports } : {}), ...(chunk.viteMetadata?.importedCss?.size ? { css: Array.from(chunk.viteMetadata.importedCss), } : {}), }, ]; return bundleManifestEntry; }) .filter(Boolean) ); return bundleManifest; }