import type { OutputBundle, OutputChunk } from 'rollup' import type { Plugin, ResolvedConfig } from 'vite' type StyleChunk = OutputChunk & { viteMetadata?: { importedCss: Set } } function staticAssets(bundle: OutputBundle, entry: OutputChunk): Set { const assets = new Set() const visit = (chunk: StyleChunk) => { if (assets.has(chunk.fileName)) return assets.add(chunk.fileName) for (const css of chunk.viteMetadata?.importedCss ?? []) assets.add(css) for (const file of chunk.imports) { const dependency = bundle[file] if (dependency?.type === 'chunk') visit(dependency) } } visit(entry) return assets } // Download route resources without evaluating the module or applying its CSS. export function loginRoutePreload(): Plugin { let config: ResolvedConfig return { name: 'login-route-preload', apply: 'build', configResolved(resolved) { config = resolved }, transformIndexHtml: { order: 'post', handler(_html, context) { if (context.path !== '/index.html' || !context.bundle) return const bundle = context.bundle const chunks = Object.values(bundle).filter((item): item is OutputChunk => item.type === 'chunk') const main = chunks.find(chunk => chunk.facadeModuleId === context.filename) const login = chunks.find(chunk => chunk.facadeModuleId?.replaceAll('\\', '/').endsWith('/src/views/auth/Login.vue')) if (!main || !login) throw new Error('Login route preload could not resolve the main and login chunks') const shared = staticAssets(bundle, main) const files = [...staticAssets(bundle, login)].filter(file => !shared.has(file)) const json = (value: unknown) => JSON.stringify(value).replaceAll('<', '\\u003c') return [{ tag: 'script', attrs: { 'data-login-route-preload': '' }, injectTo: 'head-prepend', children: `(function(){try{ var base=${json(config.base)},path=location.pathname; if(base==='./'||base==='')return; var prefix=new URL(base,location.href).pathname; if(path.indexOf(prefix)!==0)return; path=path.slice(prefix.length); if(path!=='login'&&path!=='login/'&&path!=='register'&&path!=='register/')return; ${json(files)}.forEach(function(file){ var link=document.createElement('link'),css=file.endsWith('.css'); if(!css&&(!link.relList||!link.relList.supports('modulepreload')))return; link.rel=css?'preload':'modulepreload'; if(css)link.as='style'; link.crossOrigin='';link.href=base+file; link.setAttribute('data-login-route-preload',''); document.head.appendChild(link); }); }catch(_){}})();`, }] }, }, } }