UNPKG

vite-plugin-entry-shaking-debugger

Version:
89 lines (76 loc) 3.12 kB
import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import type { ViteDevServer } from 'vite'; import sirv from 'sirv'; import colors from 'picocolors'; import type { Context } from 'vite-plugin-entry-shaking'; import type { ConsumerPackageInfo } from '../types'; import { PLUGIN_NAME, VERSION } from '../constants'; import { createChannel } from './channel'; import { getConsumerPackageInfo } from './paths'; const PATH_TO_CLIENT = resolve(dirname(fileURLToPath(import.meta.url)), '../dist/client'); /** * Attaches a debugger to a Vite dev server instance. * @param server Vite dev server instance. * @param ctx Plugin context. */ export async function attachDebugger(server: ViteDevServer, ctx: Context) { const { base } = server.config; const debuggerPath = `${base}__debugger`; const sirvConfig = { dev: true, single: true }; server.middlewares.use(debuggerPath, sirv(PATH_TO_CLIENT, sirvConfig)); const consumer = await getConsumerPackageInfo(); createChannel(server, ctx, consumer); printUrls(server, debuggerPath, consumer); } /** * Hijacks Vite's printUrls method to append debugger's URL. * @param server Vite dev server instance. * @param debuggerRoute Route to plugin's debugger client. * @param consumer Information about the consuming package. */ function printUrls(server: ViteDevServer, debuggerRoute: string, consumer: ConsumerPackageInfo) { // eslint-disable-next-line @typescript-eslint/unbound-method const printViteUrls = server.printUrls; server.printUrls = () => { printViteUrls(); const resolvedLocalUrls = server.resolvedUrls?.local ?? []; const pluginHeader = colors.green(`${colors.bold(PLUGIN_NAME)} v${VERSION}`); const pluginName = colors.dim('debugger'); server.config.logger.info(`\n ${pluginHeader} ${pluginName}\n`); resolvedLocalUrls.forEach((url, i) => { const baseUrl = url.endsWith('/') && debuggerRoute.startsWith('/') ? url.slice(0, -1) : url; const debugPath = debuggerRoute.endsWith('/') ? debuggerRoute : `${debuggerRoute}/`; const debugUrl = `${baseUrl}${debugPath}`; if (!i) { openBrowser(baseUrl); openBrowser(debugUrl, 300); } server.config.logger.info( colors.dim(colors.green(' ➜')) + colors.dim(` ${colors.bold('Local:')} ${colors.cyan(debugUrl)}`), ); if (consumer.name && consumer.version) { const debuggee = `${consumer.name}@${consumer.version}`; server.config.logger.info( colors.dim(colors.green(' ➜')) + colors.dim(` Debugging ${colors.bold(debuggee)}`), ); } }); }; } /** * Opens a browser window with the given address. * @param address Target address to open. * @param delay Delay before opening the browser. */ function openBrowser(address: string, delay = 0) { setTimeout(() => { import('open') .then((r) => r.default(address, { newInstance: true })) .catch(() => { // Silent error, debugger should still be accessible from printed url. }); }, delay); } export default attachDebugger;