@lytjs/plugin-vite 6.5.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"names":["parseSFC","compileSFC"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * @lytjs/plugin-vite - Options and configuration\r\n */\r\n\r\nexport interface LytjsPluginOptions {\r\n include?: RegExp | RegExp[];\r\n exclude?: RegExp | RegExp[];\r\n ssr?: boolean;\r\n signalMode?: boolean;\r\n /** Phase 1.2: 启用 Vapor HMR 支持 */\r\n enableVaporHMR?: boolean;\r\n}\r\n\r\n/**\r\n * Default plugin options\r\n */\r\nexport const defaultOptions: Required<LytjsPluginOptions> = {\r\n include: [/\\.lyt$/],\r\n exclude: [/node_modules/, /\\.git/],\r\n ssr: false,\r\n signalMode: false,\r\n enableVaporHMR: false,\r\n};\r\n\r\n/**\r\n * Resolve user options with defaults\r\n */\r\nexport function resolveOptions(options: LytjsPluginOptions): Required<LytjsPluginOptions> {\r\n return {\r\n include: options.include ?? defaultOptions.include,\r\n exclude: options.exclude ?? defaultOptions.exclude,\r\n ssr: options.ssr ?? defaultOptions.ssr,\r\n signalMode: options.signalMode ?? defaultOptions.signalMode,\r\n enableVaporHMR: options.enableVaporHMR ?? defaultOptions.enableVaporHMR,\r\n };\r\n}\r\n\r\n/**\r\n * Validate plugin options\r\n */\r\nexport function validateOptions(options: LytjsPluginOptions): void {\r\n if (options.include && !Array.isArray(options.include) && !(options.include instanceof RegExp)) {\r\n throw new TypeError('[@lytjs/plugin-vite] Option \"include\" must be a RegExp or an array of RegExp');\r\n }\r\n if (options.exclude && !Array.isArray(options.exclude) && !(options.exclude instanceof RegExp)) {\r\n throw new TypeError('[@lytjs/plugin-vite] Option \"exclude\" must be a RegExp or an array of RegExp');\r\n }\r\n}\r\n","/**\r\n * @lytjs/plugin-vite - Utility functions\r\n */\r\n\r\nimport type { LytjsPluginOptions } from './options';\r\n\r\n/**\r\n * Create a filter function for file matching\r\n */\r\nexport function createFilter(\r\n include: LytjsPluginOptions['include'],\r\n exclude: LytjsPluginOptions['exclude'],\r\n): (id: string) => boolean {\r\n const includes = Array.isArray(include) ? include : include ? [include] : [];\r\n const excludes = Array.isArray(exclude) ? exclude : exclude ? [exclude] : [];\r\n\r\n return (id: string): boolean => {\r\n // Check excludes first\r\n for (const pattern of excludes) {\r\n if (pattern.test(id)) return false;\r\n }\r\n\r\n // Check includes\r\n if (includes.length === 0) return true; // Include all if no patterns specified\r\n\r\n for (const pattern of includes) {\r\n if (pattern.test(id)) return true;\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\n/**\r\n * Normalize path for consistent matching\r\n */\r\nexport function normalizePath(path: string): string {\r\n return path.replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Generate a scope ID for scoped styles\r\n */\r\nexport function generateScopeId(filename: string): string {\r\n const hash = filename.split('').reduce((acc, char) => {\r\n return ((acc << 5) - acc + char.charCodeAt(0)) | 0;\r\n }, 0);\r\n return `data-v-${Math.abs(hash).toString(36).substring(0, 8)}`;\r\n}\r\n","/**\r\n * @lytjs/plugin-vite\r\n *\r\n * LytJS official Vite plugin for SFC compilation, HMR, and build optimizations.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { Plugin, HmrContext } from 'vite';\r\nimport type { LytjsPluginOptions } from './options';\r\nimport type { SFCStyleBlock, SFCCustomBlock } from '@lytjs/compiler/sfc';\r\nimport { resolveOptions, defaultOptions } from './options';\r\nimport { createFilter, generateScopeId } from './utils';\r\nimport { parseSFC, compileSFC } from '@lytjs/compiler/sfc';\r\n\r\n// HMR cache for tracking component updates\r\nconst hmrCache = new Map<string, { script: string; template: string; styles: string[]; isVapor: boolean }>();\r\n\r\n// Route block collection\r\nconst routeBlockMap = new Map<string, string>();\r\n\r\n// Vapor component ID map (Phase 1.2)\r\nconst vaporComponentIdMap = new Map<string, string>();\r\n\r\n/**\r\n * Create the LytJS Vite plugin\r\n */\r\nexport default function lytjs(rawOptions: LytjsPluginOptions = {}): Plugin {\r\n const options = resolveOptions(rawOptions);\r\n const filter = createFilter(options.include, options.exclude);\r\n let isProduction = false;\r\n\r\n return {\r\n name: '@lytjs/plugin-vite',\r\n enforce: 'pre',\r\n\r\n config(_userConfig, env) {\r\n isProduction = env.mode === 'production';\r\n\r\n return {\r\n esbuild: {\r\n include: [/\\.ts$/, /\\.tsx$/],\r\n exclude: [/\\.lyt$/],\r\n },\r\n optimizeDeps: {\r\n exclude: ['@lytjs/core', '@lytjs/compiler'],\r\n },\r\n };\r\n },\r\n\r\n resolveId(id) {\r\n // Handle .lyt imports\r\n if (filter(id)) {\r\n return id;\r\n }\r\n // Handle .route virtual modules\r\n if (id.endsWith('.route')) {\r\n return `\\0virtual-route:${id}`;\r\n }\r\n return null;\r\n },\r\n\r\n load(id) {\r\n if (!filter(id)) {\r\n // Handle virtual route modules\r\n if (id.startsWith('\\0virtual-route:')) {\r\n const sourceId = id.replace('\\0virtual-route:', '');\r\n const routeContent = routeBlockMap.get(sourceId);\r\n if (routeContent) {\r\n return `export default ${routeContent}`;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n return null;\r\n },\r\n\r\n transform(code, id) {\r\n if (!filter(id)) return null;\r\n\r\n try {\r\n // Parse the SFC\r\n const descriptor = parseSFC(code, { filename: id });\r\n\r\n // Handle <route> custom block\r\n const routeBlock = descriptor.customBlocks.find(\r\n (block: SFCCustomBlock) => block.type === 'route'\r\n );\r\n if (routeBlock) {\r\n // Store route info for later collection\r\n routeBlockMap.set(id, routeBlock.content);\r\n }\r\n\r\n // Generate the component code\r\n const result = compileSFC(descriptor, {\r\n filename: id,\r\n ssr: options.ssr,\r\n rendererMode: options.signalMode ? 'signal' : 'vnode',\r\n });\r\n\r\n let compiledCode = result.code;\r\n\r\n // Handle scoped styles - inject scope attribute\r\n const scopedStyles = descriptor.styles.filter((s: SFCStyleBlock) => s.scoped);\r\n if (scopedStyles.length > 0) {\r\n const scopeId = generateScopeId(id);\r\n // Inject __scopeId into the component setup\r\n compiledCode = compiledCode.replace(\r\n /(export default\\s*\\{)/,\r\n `$1\\n __scopeId: '${scopeId}',`\r\n );\r\n }\r\n\r\n // Cache for HMR\r\n if (!isProduction) {\r\n hmrCache.set(id, {\r\n script: descriptor.script?.content || '',\r\n template: descriptor.template?.content || '',\r\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\r\n isVapor: options.signalMode || false,\r\n });\r\n }\r\n\r\n // Add HMR accept for development\r\n if (!isProduction) {\r\n // Phase 1.2: Vapor HMR 支持\r\n if (options.signalMode && options.enableVaporHMR !== false) {\r\n const componentId = `vapor-${id.replace(/[^a-zA-Z0-9]/g, '_')}`;\r\n vaporComponentIdMap.set(id, componentId);\r\n compiledCode += `\r\nif (import.meta.hot) {\r\n import.meta.hot.accept((newModule) => {\r\n if (newModule && newModule.default) {\r\n // Vapor HMR: 更新组件定义,保留状态\r\n const registry = window.__LYTJS_HMR_REGISTRY__;\r\n if (registry) {\r\n const instance = registry.get('${componentId}');\r\n if (instance) {\r\n instance.component = newModule.default;\r\n // Signal 模式会自动通过 effect 重新渲染\r\n console.log('[LytJS HMR] Vapor component updated: ${id}');\r\n }\r\n }\r\n }\r\n });\r\n}\r\n`;\r\n } else {\r\n compiledCode += '\\nif (import.meta.hot) { import.meta.hot.accept(); }\\n';\r\n }\r\n }\r\n\r\n return {\r\n code: compiledCode,\r\n map: result.sourceMap as any,\r\n };\r\n } catch (error) {\r\n // Log compilation errors\r\n console.error(`[@lytjs/plugin-vite] Error compiling ${id}:`, error);\r\n\r\n // Return error overlay in development\r\n if (!isProduction) {\r\n return {\r\n code: `\r\n export default function ErrorComponent() {\r\n throw new Error(${JSON.stringify(\r\n error instanceof Error ? error.message : String(error)\r\n )});\r\n }\r\n `,\r\n map: null,\r\n };\r\n }\r\n\r\n throw error;\r\n }\r\n },\r\n\r\n async handleHotUpdate(ctx: HmrContext) {\r\n const { file, server, modules } = ctx;\r\n\r\n if (!filter(file)) return;\r\n\r\n const prevCache = hmrCache.get(file);\r\n if (!prevCache) return modules;\r\n\r\n try {\r\n // Read the updated file content\r\n const content = await ctx.read();\r\n const descriptor = parseSFC(content, { filename: file });\r\n\r\n const newCache = {\r\n script: descriptor.script?.content || '',\r\n template: descriptor.template?.content || '',\r\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\r\n isVapor: prevCache.isVapor,\r\n };\r\n\r\n // Determine what changed\r\n const scriptChanged = prevCache.script !== newCache.script;\r\n const templateChanged = prevCache.template !== newCache.template;\r\n const stylesChanged =\r\n prevCache.styles.length !== newCache.styles.length ||\r\n prevCache.styles.some((s: string, i: number) => s !== newCache.styles[i]);\r\n\r\n // Update cache\r\n hmrCache.set(file, newCache);\r\n\r\n // If script changed, full reload needed\r\n if (scriptChanged) {\r\n server.ws.send({\r\n type: 'full-reload',\r\n path: '*',\r\n });\r\n return [];\r\n }\r\n\r\n // If only template changed, we can do a hot update\r\n if (templateChanged && !stylesChanged) {\r\n // The transform hook will recompile the component\r\n return modules;\r\n }\r\n\r\n // If styles changed, we can handle CSS HMR separately\r\n if (stylesChanged && !templateChanged) {\r\n // Return the modules for CSS update\r\n return modules;\r\n }\r\n\r\n // Multiple changes, let Vite handle it\r\n return modules;\r\n } catch (error) {\r\n console.error(`[@lytjs/plugin-vite] HMR error for ${file}:`, error);\r\n return modules;\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport type { LytjsPluginOptions };\r\nexport { defaultOptions, resolveOptions };\r\n"]}
1
+ {"version":3,"sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"names":["parseSFC","compileSFC"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @lytjs/plugin-vite - Options and configuration\n */\n\nexport interface LytjsPluginOptions {\n include?: RegExp | RegExp[];\n exclude?: RegExp | RegExp[];\n ssr?: boolean;\n signalMode?: boolean;\n /** Phase 1.2: 启用 Vapor HMR 支持 */\n enableVaporHMR?: boolean;\n}\n\n/**\n * Default plugin options\n */\nexport const defaultOptions: Required<LytjsPluginOptions> = {\n include: [/\\.lyt$/],\n exclude: [/node_modules/, /\\.git/],\n ssr: false,\n signalMode: false,\n enableVaporHMR: false,\n};\n\n/**\n * Resolve user options with defaults\n */\nexport function resolveOptions(options: LytjsPluginOptions): Required<LytjsPluginOptions> {\n return {\n include: options.include ?? defaultOptions.include,\n exclude: options.exclude ?? defaultOptions.exclude,\n ssr: options.ssr ?? defaultOptions.ssr,\n signalMode: options.signalMode ?? defaultOptions.signalMode,\n enableVaporHMR: options.enableVaporHMR ?? defaultOptions.enableVaporHMR,\n };\n}\n\n/**\n * Validate plugin options\n */\nexport function validateOptions(options: LytjsPluginOptions): void {\n if (options.include && !Array.isArray(options.include) && !(options.include instanceof RegExp)) {\n throw new TypeError(\n '[@lytjs/plugin-vite] Option \"include\" must be a RegExp or an array of RegExp',\n );\n }\n if (options.exclude && !Array.isArray(options.exclude) && !(options.exclude instanceof RegExp)) {\n throw new TypeError(\n '[@lytjs/plugin-vite] Option \"exclude\" must be a RegExp or an array of RegExp',\n );\n }\n}\n","/**\n * @lytjs/plugin-vite - Utility functions\n */\n\nimport type { LytjsPluginOptions } from './options';\n\n/**\n * Create a filter function for file matching\n */\nexport function createFilter(\n include: LytjsPluginOptions['include'],\n exclude: LytjsPluginOptions['exclude'],\n): (id: string) => boolean {\n const includes = Array.isArray(include) ? include : include ? [include] : [];\n const excludes = Array.isArray(exclude) ? exclude : exclude ? [exclude] : [];\n\n return (id: string): boolean => {\n // Check excludes first\n for (const pattern of excludes) {\n if (pattern.test(id)) return false;\n }\n\n // Check includes\n if (includes.length === 0) return true; // Include all if no patterns specified\n\n for (const pattern of includes) {\n if (pattern.test(id)) return true;\n }\n\n return false;\n };\n}\n\n/**\n * Normalize path for consistent matching\n */\nexport function normalizePath(path: string): string {\n return path.replace(/\\\\/g, '/');\n}\n\n/**\n * Generate a scope ID for scoped styles\n */\nexport function generateScopeId(filename: string): string {\n const hash = filename.split('').reduce((acc, char) => {\n return ((acc << 5) - acc + char.charCodeAt(0)) | 0;\n }, 0);\n return `data-v-${Math.abs(hash).toString(36).substring(0, 8)}`;\n}\n","/**\n * @lytjs/plugin-vite\n *\n * LytJS official Vite plugin for SFC compilation, HMR, and build optimizations.\n *\n * @packageDocumentation\n */\n\nimport type { Plugin, HmrContext } from 'vite';\nimport type { LytjsPluginOptions } from './options';\nimport type { SFCStyleBlock, SFCCustomBlock } from '@lytjs/compiler/sfc';\nimport { resolveOptions, defaultOptions } from './options';\nimport { createFilter, generateScopeId } from './utils';\nimport { parseSFC, compileSFC } from '@lytjs/compiler/sfc';\n\n// HMR cache for tracking component updates\nconst hmrCache = new Map<\n string,\n { script: string; template: string; styles: string[]; isVapor: boolean }\n>();\n\n// Route block collection\nconst routeBlockMap = new Map<string, string>();\n\n// Vapor component ID map (Phase 1.2)\nconst vaporComponentIdMap = new Map<string, string>();\n\n/**\n * Create the LytJS Vite plugin\n */\nexport default function lytjs(rawOptions: LytjsPluginOptions = {}): Plugin {\n const options = resolveOptions(rawOptions);\n const filter = createFilter(options.include, options.exclude);\n let isProduction = false;\n\n return {\n name: '@lytjs/plugin-vite',\n enforce: 'pre',\n\n config(_userConfig, env) {\n isProduction = env.mode === 'production';\n\n return {\n esbuild: {\n include: [/\\.ts$/, /\\.tsx$/],\n exclude: [/\\.lyt$/],\n },\n optimizeDeps: {\n exclude: ['@lytjs/core', '@lytjs/compiler'],\n },\n };\n },\n\n resolveId(id) {\n // Handle .lyt imports\n if (filter(id)) {\n return id;\n }\n // Handle .route virtual modules\n if (id.endsWith('.route')) {\n return `\\0virtual-route:${id}`;\n }\n return null;\n },\n\n load(id) {\n if (!filter(id)) {\n // Handle virtual route modules\n if (id.startsWith('\\0virtual-route:')) {\n const sourceId = id.replace('\\0virtual-route:', '');\n const routeContent = routeBlockMap.get(sourceId);\n if (routeContent) {\n return `export default ${routeContent}`;\n }\n }\n return null;\n }\n\n return null;\n },\n\n transform(code, id) {\n if (!filter(id)) return null;\n\n try {\n // Parse the SFC\n const descriptor = parseSFC(code, { filename: id });\n\n // Handle <route> custom block\n const routeBlock = descriptor.customBlocks.find(\n (block: SFCCustomBlock) => block.type === 'route',\n );\n if (routeBlock) {\n // Store route info for later collection\n routeBlockMap.set(id, routeBlock.content);\n }\n\n // Generate the component code\n const result = compileSFC(descriptor, {\n filename: id,\n ssr: options.ssr,\n rendererMode: options.signalMode ? 'signal' : 'vnode',\n });\n\n let compiledCode = result.code;\n\n // Handle scoped styles - inject scope attribute\n const scopedStyles = descriptor.styles.filter((s: SFCStyleBlock) => s.scoped);\n if (scopedStyles.length > 0) {\n const scopeId = generateScopeId(id);\n // Inject __scopeId into the component setup\n compiledCode = compiledCode.replace(\n /(export default\\s*\\{)/,\n `$1\\n __scopeId: '${scopeId}',`,\n );\n }\n\n // Cache for HMR\n if (!isProduction) {\n hmrCache.set(id, {\n script: descriptor.script?.content || '',\n template: descriptor.template?.content || '',\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\n isVapor: options.signalMode || false,\n });\n }\n\n // Add HMR accept for development\n if (!isProduction) {\n // Phase 1.2: Vapor HMR 支持\n if (options.signalMode && options.enableVaporHMR !== false) {\n const componentId = `vapor-${id.replace(/[^a-zA-Z0-9]/g, '_')}`;\n vaporComponentIdMap.set(id, componentId);\n compiledCode += `\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (newModule && newModule.default) {\n // Vapor HMR: 更新组件定义,保留状态\n const registry = window.__LYTJS_HMR_REGISTRY__;\n if (registry) {\n const instance = registry.get('${componentId}');\n if (instance) {\n instance.component = newModule.default;\n // Signal 模式会自动通过 effect 重新渲染\n console.log('[LytJS HMR] Vapor component updated: ${id}');\n }\n }\n }\n });\n}\n`;\n } else {\n compiledCode += '\\nif (import.meta.hot) { import.meta.hot.accept(); }\\n';\n }\n }\n\n return {\n code: compiledCode,\n map: result.sourceMap,\n };\n } catch (error) {\n // Log compilation errors\n console.error(`[@lytjs/plugin-vite] Error compiling ${id}:`, error);\n\n // Return error overlay in development\n if (!isProduction) {\n return {\n code: `\n export default function ErrorComponent() {\n throw new Error(${JSON.stringify(\n error instanceof Error ? error.message : String(error),\n )});\n }\n `,\n map: null,\n };\n }\n\n throw error;\n }\n },\n\n async handleHotUpdate(ctx: HmrContext) {\n const { file, server, modules } = ctx;\n\n if (!filter(file)) return;\n\n const prevCache = hmrCache.get(file);\n if (!prevCache) return modules;\n\n try {\n // Read the updated file content\n const content = await ctx.read();\n const descriptor = parseSFC(content, { filename: file });\n\n const newCache = {\n script: descriptor.script?.content || '',\n template: descriptor.template?.content || '',\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\n isVapor: prevCache.isVapor,\n };\n\n // Determine what changed\n const scriptChanged = prevCache.script !== newCache.script;\n const templateChanged = prevCache.template !== newCache.template;\n const stylesChanged =\n prevCache.styles.length !== newCache.styles.length ||\n prevCache.styles.some((s: string, i: number) => s !== newCache.styles[i]);\n\n // Update cache\n hmrCache.set(file, newCache);\n\n // If script changed, full reload needed\n if (scriptChanged) {\n server.ws.send({\n type: 'full-reload',\n path: '*',\n });\n return [];\n }\n\n // If only template changed, we can do a hot update\n if (templateChanged && !stylesChanged) {\n // The transform hook will recompile the component\n return modules;\n }\n\n // If styles changed, we can handle CSS HMR separately\n if (stylesChanged && !templateChanged) {\n // Return the modules for CSS update\n return modules;\n }\n\n // Multiple changes, let Vite handle it\n return modules;\n } catch (error) {\n console.error(`[@lytjs/plugin-vite] HMR error for ${file}:`, error);\n return modules;\n }\n },\n };\n}\n\nexport type { LytjsPluginOptions };\nexport { defaultOptions, resolveOptions };\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * @lytjs/plugin-vite - Options and configuration\r\n */\r\n\r\nexport interface LytjsPluginOptions {\r\n include?: RegExp | RegExp[];\r\n exclude?: RegExp | RegExp[];\r\n ssr?: boolean;\r\n signalMode?: boolean;\r\n /** Phase 1.2: 启用 Vapor HMR 支持 */\r\n enableVaporHMR?: boolean;\r\n}\r\n\r\n/**\r\n * Default plugin options\r\n */\r\nexport const defaultOptions: Required<LytjsPluginOptions> = {\r\n include: [/\\.lyt$/],\r\n exclude: [/node_modules/, /\\.git/],\r\n ssr: false,\r\n signalMode: false,\r\n enableVaporHMR: false,\r\n};\r\n\r\n/**\r\n * Resolve user options with defaults\r\n */\r\nexport function resolveOptions(options: LytjsPluginOptions): Required<LytjsPluginOptions> {\r\n return {\r\n include: options.include ?? defaultOptions.include,\r\n exclude: options.exclude ?? defaultOptions.exclude,\r\n ssr: options.ssr ?? defaultOptions.ssr,\r\n signalMode: options.signalMode ?? defaultOptions.signalMode,\r\n enableVaporHMR: options.enableVaporHMR ?? defaultOptions.enableVaporHMR,\r\n };\r\n}\r\n\r\n/**\r\n * Validate plugin options\r\n */\r\nexport function validateOptions(options: LytjsPluginOptions): void {\r\n if (options.include && !Array.isArray(options.include) && !(options.include instanceof RegExp)) {\r\n throw new TypeError('[@lytjs/plugin-vite] Option \"include\" must be a RegExp or an array of RegExp');\r\n }\r\n if (options.exclude && !Array.isArray(options.exclude) && !(options.exclude instanceof RegExp)) {\r\n throw new TypeError('[@lytjs/plugin-vite] Option \"exclude\" must be a RegExp or an array of RegExp');\r\n }\r\n}\r\n","/**\r\n * @lytjs/plugin-vite - Utility functions\r\n */\r\n\r\nimport type { LytjsPluginOptions } from './options';\r\n\r\n/**\r\n * Create a filter function for file matching\r\n */\r\nexport function createFilter(\r\n include: LytjsPluginOptions['include'],\r\n exclude: LytjsPluginOptions['exclude'],\r\n): (id: string) => boolean {\r\n const includes = Array.isArray(include) ? include : include ? [include] : [];\r\n const excludes = Array.isArray(exclude) ? exclude : exclude ? [exclude] : [];\r\n\r\n return (id: string): boolean => {\r\n // Check excludes first\r\n for (const pattern of excludes) {\r\n if (pattern.test(id)) return false;\r\n }\r\n\r\n // Check includes\r\n if (includes.length === 0) return true; // Include all if no patterns specified\r\n\r\n for (const pattern of includes) {\r\n if (pattern.test(id)) return true;\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\n/**\r\n * Normalize path for consistent matching\r\n */\r\nexport function normalizePath(path: string): string {\r\n return path.replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Generate a scope ID for scoped styles\r\n */\r\nexport function generateScopeId(filename: string): string {\r\n const hash = filename.split('').reduce((acc, char) => {\r\n return ((acc << 5) - acc + char.charCodeAt(0)) | 0;\r\n }, 0);\r\n return `data-v-${Math.abs(hash).toString(36).substring(0, 8)}`;\r\n}\r\n","/**\r\n * @lytjs/plugin-vite\r\n *\r\n * LytJS official Vite plugin for SFC compilation, HMR, and build optimizations.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { Plugin, HmrContext } from 'vite';\r\nimport type { LytjsPluginOptions } from './options';\r\nimport type { SFCStyleBlock, SFCCustomBlock } from '@lytjs/compiler/sfc';\r\nimport { resolveOptions, defaultOptions } from './options';\r\nimport { createFilter, generateScopeId } from './utils';\r\nimport { parseSFC, compileSFC } from '@lytjs/compiler/sfc';\r\n\r\n// HMR cache for tracking component updates\r\nconst hmrCache = new Map<string, { script: string; template: string; styles: string[]; isVapor: boolean }>();\r\n\r\n// Route block collection\r\nconst routeBlockMap = new Map<string, string>();\r\n\r\n// Vapor component ID map (Phase 1.2)\r\nconst vaporComponentIdMap = new Map<string, string>();\r\n\r\n/**\r\n * Create the LytJS Vite plugin\r\n */\r\nexport default function lytjs(rawOptions: LytjsPluginOptions = {}): Plugin {\r\n const options = resolveOptions(rawOptions);\r\n const filter = createFilter(options.include, options.exclude);\r\n let isProduction = false;\r\n\r\n return {\r\n name: '@lytjs/plugin-vite',\r\n enforce: 'pre',\r\n\r\n config(_userConfig, env) {\r\n isProduction = env.mode === 'production';\r\n\r\n return {\r\n esbuild: {\r\n include: [/\\.ts$/, /\\.tsx$/],\r\n exclude: [/\\.lyt$/],\r\n },\r\n optimizeDeps: {\r\n exclude: ['@lytjs/core', '@lytjs/compiler'],\r\n },\r\n };\r\n },\r\n\r\n resolveId(id) {\r\n // Handle .lyt imports\r\n if (filter(id)) {\r\n return id;\r\n }\r\n // Handle .route virtual modules\r\n if (id.endsWith('.route')) {\r\n return `\\0virtual-route:${id}`;\r\n }\r\n return null;\r\n },\r\n\r\n load(id) {\r\n if (!filter(id)) {\r\n // Handle virtual route modules\r\n if (id.startsWith('\\0virtual-route:')) {\r\n const sourceId = id.replace('\\0virtual-route:', '');\r\n const routeContent = routeBlockMap.get(sourceId);\r\n if (routeContent) {\r\n return `export default ${routeContent}`;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n return null;\r\n },\r\n\r\n transform(code, id) {\r\n if (!filter(id)) return null;\r\n\r\n try {\r\n // Parse the SFC\r\n const descriptor = parseSFC(code, { filename: id });\r\n\r\n // Handle <route> custom block\r\n const routeBlock = descriptor.customBlocks.find(\r\n (block: SFCCustomBlock) => block.type === 'route'\r\n );\r\n if (routeBlock) {\r\n // Store route info for later collection\r\n routeBlockMap.set(id, routeBlock.content);\r\n }\r\n\r\n // Generate the component code\r\n const result = compileSFC(descriptor, {\r\n filename: id,\r\n ssr: options.ssr,\r\n rendererMode: options.signalMode ? 'signal' : 'vnode',\r\n });\r\n\r\n let compiledCode = result.code;\r\n\r\n // Handle scoped styles - inject scope attribute\r\n const scopedStyles = descriptor.styles.filter((s: SFCStyleBlock) => s.scoped);\r\n if (scopedStyles.length > 0) {\r\n const scopeId = generateScopeId(id);\r\n // Inject __scopeId into the component setup\r\n compiledCode = compiledCode.replace(\r\n /(export default\\s*\\{)/,\r\n `$1\\n __scopeId: '${scopeId}',`\r\n );\r\n }\r\n\r\n // Cache for HMR\r\n if (!isProduction) {\r\n hmrCache.set(id, {\r\n script: descriptor.script?.content || '',\r\n template: descriptor.template?.content || '',\r\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\r\n isVapor: options.signalMode || false,\r\n });\r\n }\r\n\r\n // Add HMR accept for development\r\n if (!isProduction) {\r\n // Phase 1.2: Vapor HMR 支持\r\n if (options.signalMode && options.enableVaporHMR !== false) {\r\n const componentId = `vapor-${id.replace(/[^a-zA-Z0-9]/g, '_')}`;\r\n vaporComponentIdMap.set(id, componentId);\r\n compiledCode += `\r\nif (import.meta.hot) {\r\n import.meta.hot.accept((newModule) => {\r\n if (newModule && newModule.default) {\r\n // Vapor HMR: 更新组件定义,保留状态\r\n const registry = window.__LYTJS_HMR_REGISTRY__;\r\n if (registry) {\r\n const instance = registry.get('${componentId}');\r\n if (instance) {\r\n instance.component = newModule.default;\r\n // Signal 模式会自动通过 effect 重新渲染\r\n console.log('[LytJS HMR] Vapor component updated: ${id}');\r\n }\r\n }\r\n }\r\n });\r\n}\r\n`;\r\n } else {\r\n compiledCode += '\\nif (import.meta.hot) { import.meta.hot.accept(); }\\n';\r\n }\r\n }\r\n\r\n return {\r\n code: compiledCode,\r\n map: result.sourceMap as any,\r\n };\r\n } catch (error) {\r\n // Log compilation errors\r\n console.error(`[@lytjs/plugin-vite] Error compiling ${id}:`, error);\r\n\r\n // Return error overlay in development\r\n if (!isProduction) {\r\n return {\r\n code: `\r\n export default function ErrorComponent() {\r\n throw new Error(${JSON.stringify(\r\n error instanceof Error ? error.message : String(error)\r\n )});\r\n }\r\n `,\r\n map: null,\r\n };\r\n }\r\n\r\n throw error;\r\n }\r\n },\r\n\r\n async handleHotUpdate(ctx: HmrContext) {\r\n const { file, server, modules } = ctx;\r\n\r\n if (!filter(file)) return;\r\n\r\n const prevCache = hmrCache.get(file);\r\n if (!prevCache) return modules;\r\n\r\n try {\r\n // Read the updated file content\r\n const content = await ctx.read();\r\n const descriptor = parseSFC(content, { filename: file });\r\n\r\n const newCache = {\r\n script: descriptor.script?.content || '',\r\n template: descriptor.template?.content || '',\r\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\r\n isVapor: prevCache.isVapor,\r\n };\r\n\r\n // Determine what changed\r\n const scriptChanged = prevCache.script !== newCache.script;\r\n const templateChanged = prevCache.template !== newCache.template;\r\n const stylesChanged =\r\n prevCache.styles.length !== newCache.styles.length ||\r\n prevCache.styles.some((s: string, i: number) => s !== newCache.styles[i]);\r\n\r\n // Update cache\r\n hmrCache.set(file, newCache);\r\n\r\n // If script changed, full reload needed\r\n if (scriptChanged) {\r\n server.ws.send({\r\n type: 'full-reload',\r\n path: '*',\r\n });\r\n return [];\r\n }\r\n\r\n // If only template changed, we can do a hot update\r\n if (templateChanged && !stylesChanged) {\r\n // The transform hook will recompile the component\r\n return modules;\r\n }\r\n\r\n // If styles changed, we can handle CSS HMR separately\r\n if (stylesChanged && !templateChanged) {\r\n // Return the modules for CSS update\r\n return modules;\r\n }\r\n\r\n // Multiple changes, let Vite handle it\r\n return modules;\r\n } catch (error) {\r\n console.error(`[@lytjs/plugin-vite] HMR error for ${file}:`, error);\r\n return modules;\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport type { LytjsPluginOptions };\r\nexport { defaultOptions, resolveOptions };\r\n"]}
1
+ {"version":3,"sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @lytjs/plugin-vite - Options and configuration\n */\n\nexport interface LytjsPluginOptions {\n include?: RegExp | RegExp[];\n exclude?: RegExp | RegExp[];\n ssr?: boolean;\n signalMode?: boolean;\n /** Phase 1.2: 启用 Vapor HMR 支持 */\n enableVaporHMR?: boolean;\n}\n\n/**\n * Default plugin options\n */\nexport const defaultOptions: Required<LytjsPluginOptions> = {\n include: [/\\.lyt$/],\n exclude: [/node_modules/, /\\.git/],\n ssr: false,\n signalMode: false,\n enableVaporHMR: false,\n};\n\n/**\n * Resolve user options with defaults\n */\nexport function resolveOptions(options: LytjsPluginOptions): Required<LytjsPluginOptions> {\n return {\n include: options.include ?? defaultOptions.include,\n exclude: options.exclude ?? defaultOptions.exclude,\n ssr: options.ssr ?? defaultOptions.ssr,\n signalMode: options.signalMode ?? defaultOptions.signalMode,\n enableVaporHMR: options.enableVaporHMR ?? defaultOptions.enableVaporHMR,\n };\n}\n\n/**\n * Validate plugin options\n */\nexport function validateOptions(options: LytjsPluginOptions): void {\n if (options.include && !Array.isArray(options.include) && !(options.include instanceof RegExp)) {\n throw new TypeError(\n '[@lytjs/plugin-vite] Option \"include\" must be a RegExp or an array of RegExp',\n );\n }\n if (options.exclude && !Array.isArray(options.exclude) && !(options.exclude instanceof RegExp)) {\n throw new TypeError(\n '[@lytjs/plugin-vite] Option \"exclude\" must be a RegExp or an array of RegExp',\n );\n }\n}\n","/**\n * @lytjs/plugin-vite - Utility functions\n */\n\nimport type { LytjsPluginOptions } from './options';\n\n/**\n * Create a filter function for file matching\n */\nexport function createFilter(\n include: LytjsPluginOptions['include'],\n exclude: LytjsPluginOptions['exclude'],\n): (id: string) => boolean {\n const includes = Array.isArray(include) ? include : include ? [include] : [];\n const excludes = Array.isArray(exclude) ? exclude : exclude ? [exclude] : [];\n\n return (id: string): boolean => {\n // Check excludes first\n for (const pattern of excludes) {\n if (pattern.test(id)) return false;\n }\n\n // Check includes\n if (includes.length === 0) return true; // Include all if no patterns specified\n\n for (const pattern of includes) {\n if (pattern.test(id)) return true;\n }\n\n return false;\n };\n}\n\n/**\n * Normalize path for consistent matching\n */\nexport function normalizePath(path: string): string {\n return path.replace(/\\\\/g, '/');\n}\n\n/**\n * Generate a scope ID for scoped styles\n */\nexport function generateScopeId(filename: string): string {\n const hash = filename.split('').reduce((acc, char) => {\n return ((acc << 5) - acc + char.charCodeAt(0)) | 0;\n }, 0);\n return `data-v-${Math.abs(hash).toString(36).substring(0, 8)}`;\n}\n","/**\n * @lytjs/plugin-vite\n *\n * LytJS official Vite plugin for SFC compilation, HMR, and build optimizations.\n *\n * @packageDocumentation\n */\n\nimport type { Plugin, HmrContext } from 'vite';\nimport type { LytjsPluginOptions } from './options';\nimport type { SFCStyleBlock, SFCCustomBlock } from '@lytjs/compiler/sfc';\nimport { resolveOptions, defaultOptions } from './options';\nimport { createFilter, generateScopeId } from './utils';\nimport { parseSFC, compileSFC } from '@lytjs/compiler/sfc';\n\n// HMR cache for tracking component updates\nconst hmrCache = new Map<\n string,\n { script: string; template: string; styles: string[]; isVapor: boolean }\n>();\n\n// Route block collection\nconst routeBlockMap = new Map<string, string>();\n\n// Vapor component ID map (Phase 1.2)\nconst vaporComponentIdMap = new Map<string, string>();\n\n/**\n * Create the LytJS Vite plugin\n */\nexport default function lytjs(rawOptions: LytjsPluginOptions = {}): Plugin {\n const options = resolveOptions(rawOptions);\n const filter = createFilter(options.include, options.exclude);\n let isProduction = false;\n\n return {\n name: '@lytjs/plugin-vite',\n enforce: 'pre',\n\n config(_userConfig, env) {\n isProduction = env.mode === 'production';\n\n return {\n esbuild: {\n include: [/\\.ts$/, /\\.tsx$/],\n exclude: [/\\.lyt$/],\n },\n optimizeDeps: {\n exclude: ['@lytjs/core', '@lytjs/compiler'],\n },\n };\n },\n\n resolveId(id) {\n // Handle .lyt imports\n if (filter(id)) {\n return id;\n }\n // Handle .route virtual modules\n if (id.endsWith('.route')) {\n return `\\0virtual-route:${id}`;\n }\n return null;\n },\n\n load(id) {\n if (!filter(id)) {\n // Handle virtual route modules\n if (id.startsWith('\\0virtual-route:')) {\n const sourceId = id.replace('\\0virtual-route:', '');\n const routeContent = routeBlockMap.get(sourceId);\n if (routeContent) {\n return `export default ${routeContent}`;\n }\n }\n return null;\n }\n\n return null;\n },\n\n transform(code, id) {\n if (!filter(id)) return null;\n\n try {\n // Parse the SFC\n const descriptor = parseSFC(code, { filename: id });\n\n // Handle <route> custom block\n const routeBlock = descriptor.customBlocks.find(\n (block: SFCCustomBlock) => block.type === 'route',\n );\n if (routeBlock) {\n // Store route info for later collection\n routeBlockMap.set(id, routeBlock.content);\n }\n\n // Generate the component code\n const result = compileSFC(descriptor, {\n filename: id,\n ssr: options.ssr,\n rendererMode: options.signalMode ? 'signal' : 'vnode',\n });\n\n let compiledCode = result.code;\n\n // Handle scoped styles - inject scope attribute\n const scopedStyles = descriptor.styles.filter((s: SFCStyleBlock) => s.scoped);\n if (scopedStyles.length > 0) {\n const scopeId = generateScopeId(id);\n // Inject __scopeId into the component setup\n compiledCode = compiledCode.replace(\n /(export default\\s*\\{)/,\n `$1\\n __scopeId: '${scopeId}',`,\n );\n }\n\n // Cache for HMR\n if (!isProduction) {\n hmrCache.set(id, {\n script: descriptor.script?.content || '',\n template: descriptor.template?.content || '',\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\n isVapor: options.signalMode || false,\n });\n }\n\n // Add HMR accept for development\n if (!isProduction) {\n // Phase 1.2: Vapor HMR 支持\n if (options.signalMode && options.enableVaporHMR !== false) {\n const componentId = `vapor-${id.replace(/[^a-zA-Z0-9]/g, '_')}`;\n vaporComponentIdMap.set(id, componentId);\n compiledCode += `\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (newModule && newModule.default) {\n // Vapor HMR: 更新组件定义,保留状态\n const registry = window.__LYTJS_HMR_REGISTRY__;\n if (registry) {\n const instance = registry.get('${componentId}');\n if (instance) {\n instance.component = newModule.default;\n // Signal 模式会自动通过 effect 重新渲染\n console.log('[LytJS HMR] Vapor component updated: ${id}');\n }\n }\n }\n });\n}\n`;\n } else {\n compiledCode += '\\nif (import.meta.hot) { import.meta.hot.accept(); }\\n';\n }\n }\n\n return {\n code: compiledCode,\n map: result.sourceMap,\n };\n } catch (error) {\n // Log compilation errors\n console.error(`[@lytjs/plugin-vite] Error compiling ${id}:`, error);\n\n // Return error overlay in development\n if (!isProduction) {\n return {\n code: `\n export default function ErrorComponent() {\n throw new Error(${JSON.stringify(\n error instanceof Error ? error.message : String(error),\n )});\n }\n `,\n map: null,\n };\n }\n\n throw error;\n }\n },\n\n async handleHotUpdate(ctx: HmrContext) {\n const { file, server, modules } = ctx;\n\n if (!filter(file)) return;\n\n const prevCache = hmrCache.get(file);\n if (!prevCache) return modules;\n\n try {\n // Read the updated file content\n const content = await ctx.read();\n const descriptor = parseSFC(content, { filename: file });\n\n const newCache = {\n script: descriptor.script?.content || '',\n template: descriptor.template?.content || '',\n styles: descriptor.styles.map((s: SFCStyleBlock) => s.content),\n isVapor: prevCache.isVapor,\n };\n\n // Determine what changed\n const scriptChanged = prevCache.script !== newCache.script;\n const templateChanged = prevCache.template !== newCache.template;\n const stylesChanged =\n prevCache.styles.length !== newCache.styles.length ||\n prevCache.styles.some((s: string, i: number) => s !== newCache.styles[i]);\n\n // Update cache\n hmrCache.set(file, newCache);\n\n // If script changed, full reload needed\n if (scriptChanged) {\n server.ws.send({\n type: 'full-reload',\n path: '*',\n });\n return [];\n }\n\n // If only template changed, we can do a hot update\n if (templateChanged && !stylesChanged) {\n // The transform hook will recompile the component\n return modules;\n }\n\n // If styles changed, we can handle CSS HMR separately\n if (stylesChanged && !templateChanged) {\n // Return the modules for CSS update\n return modules;\n }\n\n // Multiple changes, let Vite handle it\n return modules;\n } catch (error) {\n console.error(`[@lytjs/plugin-vite] HMR error for ${file}:`, error);\n return modules;\n }\n },\n };\n}\n\nexport type { LytjsPluginOptions };\nexport { defaultOptions, resolveOptions };\n"]}
package/package.json CHANGED
@@ -1,57 +1,57 @@
1
- {
2
- "name": "@lytjs/plugin-vite",
3
- "version": "6.5.0",
4
- "description": "LytJS official Vite plugin for SFC compilation, HMR, and build optimizations",
5
- "type": "module",
6
- "main": "./dist/index.cjs",
7
- "module": "./dist/index.mjs",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.mjs",
13
- "require": "./dist/index.cjs"
14
- },
15
- "./package.json": "./package.json"
16
- },
17
- "files": [
18
- "dist"
19
- ],
20
- "sideEffects": false,
21
- "scripts": {
22
- "build": "tsup",
23
- "dev": "tsup --watch",
24
- "test": "vitest run",
25
- "test:watch": "vitest",
26
- "test:coverage": "vitest run --coverage",
27
- "type-check": "tsc --noEmit",
28
- "lint": "eslint \"src/**/*.ts\"",
29
- "clean": "rm -rf dist"
30
- },
31
- "dependencies": {
32
- "@lytjs/compiler": "^6.0.0",
33
- "@lytjs/common-is": "^6.0.0"
34
- },
35
- "peerDependencies": {
36
- "vite": "^5.0.0 || ^6.0.0"
37
- },
38
- "devDependencies": {
39
- "tsup": "^8.0.0",
40
- "typescript": "^5.4.0",
41
- "vitest": "^3.0.0",
42
- "vite": "^5.0.0"
43
- },
44
- "license": "MIT",
45
- "repository": {
46
- "type": "git",
47
- "url": "https://gitee.com/lytjs/lytjs.git",
48
- "directory": "packages/plugins/packages/plugin-vite"
49
- },
50
- "keywords": [
51
- "lytjs",
52
- "vite",
53
- "plugin",
54
- "sfc",
55
- "hmr"
56
- ]
57
- }
1
+ {
2
+ "name": "@lytjs/plugin-vite",
3
+ "version": "6.6.0",
4
+ "description": "LytJS official Vite plugin for SFC compilation, HMR, and build optimizations",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "sideEffects": false,
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "test:coverage": "vitest run --coverage",
27
+ "type-check": "tsc --noEmit",
28
+ "lint": "eslint \"src/**/*.ts\"",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "dependencies": {
32
+ "@lytjs/compiler": "workspace:*",
33
+ "@lytjs/common-is": "workspace:*"
34
+ },
35
+ "peerDependencies": {
36
+ "vite": "^5.0.0 || ^6.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "tsup": "^8.0.0",
40
+ "typescript": "^5.4.0",
41
+ "vitest": "^3.0.0",
42
+ "vite": "^5.0.0"
43
+ },
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://gitee.com/lytjs/lytjs.git",
48
+ "directory": "packages/plugins/packages/plugin-vite"
49
+ },
50
+ "keywords": [
51
+ "lytjs",
52
+ "vite",
53
+ "plugin",
54
+ "sfc",
55
+ "hmr"
56
+ ]
57
+ }