diff --git a/packages/astro/package.json b/packages/astro/package.json index bd21e98d183d..881f3070421c 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -69,10 +69,12 @@ "@proload/core": "^0.2.1", "@proload/plugin-tsm": "^0.1.0", "@types/babel__core": "^7.1.15", + "@types/debug": "^4.1.7", "@web/parse5-utils": "^1.3.0", "astring": "^1.7.5", "ci-info": "^3.2.0", "common-ancestor-path": "^1.0.1", + "debug": "^4.3.3", "eol": "^0.9.1", "es-module-lexer": "^0.9.3", "esbuild": "0.13.7", diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index 17df0863a68b..024dc4d05354 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -76,7 +76,7 @@ class AstroBuilder { this.viteConfig = viteConfig; const viteServer = await vite.createServer(viteConfig); this.viteServer = viteServer; - debug(logging, 'build', timerMessage('Vite started', timer.viteStart)); + debug('build', timerMessage('Vite started', timer.viteStart)); timer.loadStart = performance.now(); const { assets, allPages } = await collectPagesData({ @@ -94,13 +94,13 @@ class AstroBuilder { // TODO: add better type inference to data.preload[1] const frontmatter = (data.preload[1] as any).frontmatter; if (Boolean(frontmatter.draft) && !this.config.buildOptions.drafts) { - debug(logging, 'build', timerMessage(`Skipping draft page ${page}`, timer.loadStart)); + debug('build', timerMessage(`Skipping draft page ${page}`, timer.loadStart)); delete allPages[page]; } } }); - debug(logging, 'build', timerMessage('All pages loaded', timer.loadStart)); + debug('build', timerMessage('All pages loaded', timer.loadStart)); // The names of each pages const pageNames: string[] = []; @@ -132,7 +132,7 @@ class AstroBuilder { viteServer: this.viteServer, }); } - debug(logging, 'build', timerMessage('Vite build finished', timer.buildStart)); + debug('build', timerMessage('Vite build finished', timer.buildStart)); // Write any additionally generated assets to disk. timer.assetsStart = performance.now(); @@ -143,7 +143,7 @@ class AstroBuilder { fs.writeFileSync(filePath, assets[k], 'utf8'); delete assets[k]; // free up memory }); - debug(logging, 'build', timerMessage('Additional assets copied', timer.assetsStart)); + debug('build', timerMessage('Additional assets copied', timer.assetsStart)); // Build your final sitemap. timer.sitemapStart = performance.now(); @@ -153,7 +153,7 @@ class AstroBuilder { await fs.promises.mkdir(new URL('./', sitemapPath), { recursive: true }); await fs.promises.writeFile(sitemapPath, sitemap, 'utf8'); } - debug(logging, 'build', timerMessage('Sitemap built', timer.sitemapStart)); + debug('build', timerMessage('Sitemap built', timer.sitemapStart)); // You're done! Time to clean up. await viteServer.close(); @@ -164,8 +164,6 @@ class AstroBuilder { /** Stats */ private async printStats({ logging, timeStart, pageCount }: { logging: LogOptions; timeStart: number; pageCount: number }) { - /* eslint-disable no-console */ - debug(logging, ''); // empty line for debug const buildTime = performance.now() - timeStart; const total = buildTime < 750 ? `${Math.round(buildTime)}ms` : `${(buildTime / 1000).toFixed(2)}s`; const perPage = `${Math.round(buildTime / pageCount)}ms`; diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts index 19c86de55f14..106e09a057e0 100644 --- a/packages/astro/src/core/build/page-data.ts +++ b/packages/astro/src/core/build/page-data.ts @@ -55,11 +55,11 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise { const html = `${route.pathname}`.replace(/\/?$/, '/index.html'); - debug(logging, 'build', `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.yellow(html)}`); + debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.yellow(html)}`); return routes; }) .catch((err) => { - debug(logging, 'build', `├── ${colors.bold(colors.red('✘'))} ${route.component}`); + debug('build', `├── ${colors.bold(colors.red('✘'))} ${route.component}`); throw err; }), }; @@ -69,11 +69,11 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise { const label = _result.staticPaths.length === 1 ? 'page' : 'pages'; - debug(logging, 'build', `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta(`[${_result.staticPaths.length} ${label}]`)}`); + debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta(`[${_result.staticPaths.length} ${label}]`)}`); return _result; }) .catch((err) => { - debug(logging, 'build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`); + debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`); throw err; }); const rssFn = generateRssFunction(astroConfig.buildOptions.site, route); diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 453666adb216..ad2b51203988 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -256,7 +256,7 @@ async function collectRenderers(opts: StaticBuildOptions): Promise { } async function generatePages(result: RollupOutput, opts: StaticBuildOptions, internals: BuildInternals, facadeIdToPageDataMap: Map) { - debug(opts.logging, 'generate', 'End build step, now generating'); + debug('build', 'Finish build. Begin generating.'); // Get renderers to be shared for each page generation. const renderers = await collectRenderers(opts); @@ -331,11 +331,10 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G const [params, pageProps] = await getParamsAndProps({ route: pageData.route, routeCache, - logging, pathname, }); - debug(logging, 'generate', `Generating: ${pathname}`); + debug('build', `Generating: ${pathname}`); const rootpath = new URL(astroConfig.buildOptions.site || 'http://localhost/').pathname; const links = new Set( diff --git a/packages/astro/src/core/logger.ts b/packages/astro/src/core/logger.ts index ed6240bcc616..c00e71347abb 100644 --- a/packages/astro/src/core/logger.ts +++ b/packages/astro/src/core/logger.ts @@ -4,6 +4,7 @@ import { bold, blue, dim, red, grey, underline, yellow } from 'kleur/colors'; import { performance } from 'perf_hooks'; import { Writable } from 'stream'; import stringWidth from 'string-width'; +import debugPackage from 'debug'; import { format as utilFormat } from 'util'; type ConsoleStream = Writable & { @@ -61,7 +62,7 @@ interface LogWritable extends Writable { } export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; // same as Pino -export type LoggerEvent = 'debug' | 'info' | 'warn' | 'error'; +export type LoggerEvent = 'info' | 'warn' | 'error'; export interface LogOptions { dest?: LogWritable; @@ -107,27 +108,35 @@ export function log(opts: LogOptions = {}, level: LoggerLevel, type: string | nu dest.write(event); } -/** Emit a message only shown in debug mode */ -export function debug(opts: LogOptions, type: string | null, ...messages: Array) { - return log(opts, 'debug', type, ...messages); +const debuggers: Record = {}; +/** + * Emit a message only shown in debug mode. + * Astro (along with many of its dependencies) uses the `debug` package for debug logging. + * You can enable these logs with the `DEBUG=astro:*` environment variable. + * More info https://github.com/debug-js/debug#environment-variables + */ +export function debug(type: string, ...messages: Array) { + const namespace = `astro:${type}`; + debuggers[namespace] = debuggers[namespace] || debugPackage(namespace); + return debuggers[namespace](messages); } -/** Emit a general info message (be careful using this too much!) */ +/** Emit a user-facing message. Useful for UI and other console messages. */ export function info(opts: LogOptions, type: string | null, ...messages: Array) { return log(opts, 'info', type, ...messages); } -/** Emit a warning a user should be aware of */ +/** Emit a warning message. Useful for high-priority messages that aren't necessarily errors. */ export function warn(opts: LogOptions, type: string | null, ...messages: Array) { return log(opts, 'warn', type, ...messages); } -/** Emit a fatal error message the user should address. */ +/** Emit a error message, Useful when Astro can't recover from some error. */ export function error(opts: LogOptions, type: string | null, ...messages: Array) { return log(opts, 'error', type, ...messages); } -type LogFn = typeof debug | typeof info | typeof warn | typeof error; +type LogFn = typeof info | typeof warn | typeof error; export function table(opts: LogOptions, columns: number[]) { return function logTable(logFn: LogFn, ...input: Array) { @@ -163,7 +172,6 @@ ${frame} // A default logger for when too lazy to pass LogOptions around. export const logger = { - debug: debug.bind(null, defaultLogOptions), info: info.bind(null, defaultLogOptions), warn: warn.bind(null, defaultLogOptions), error: error.bind(null, defaultLogOptions), diff --git a/packages/astro/src/core/ssr/index.ts b/packages/astro/src/core/ssr/index.ts index cb4d09797f4e..c4d214a72589 100644 --- a/packages/astro/src/core/ssr/index.ts +++ b/packages/astro/src/core/ssr/index.ts @@ -125,17 +125,7 @@ export async function preload({ astroConfig, filePath, viteServer }: SSROptions) return [renderers, mod]; } -export async function getParamsAndProps({ - route, - routeCache, - pathname, - logging, -}: { - route: RouteData | undefined; - routeCache: RouteCache; - pathname: string; - logging: LogOptions; -}): Promise<[Params, Props]> { +export async function getParamsAndProps({ route, routeCache, pathname }: { route: RouteData | undefined; routeCache: RouteCache; pathname: string }): Promise<[Params, Props]> { // Handle dynamic routes let params: Params = {}; let pageProps: Props; @@ -151,7 +141,7 @@ export async function getParamsAndProps({ throw new Error(`[${route.component}] Internal error: route cache was empty, but expected to be full.`); } const paramsKey = JSON.stringify(params); - const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, paramsKey, logging); + const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, paramsKey); if (!matchedStaticPath) { throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`); } diff --git a/packages/astro/src/core/ssr/route-cache.ts b/packages/astro/src/core/ssr/route-cache.ts index f2dd9f4588ef..11988d36b89f 100644 --- a/packages/astro/src/core/ssr/route-cache.ts +++ b/packages/astro/src/core/ssr/route-cache.ts @@ -73,12 +73,12 @@ export class RouteCache { } } -export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, paramsKey: string, logging: LogOptions) { +export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, paramsKey: string) { let matchedStaticPath = staticPaths.keyed.get(paramsKey); if (matchedStaticPath) { return matchedStaticPath; } - debug(logging, 'findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`); + debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`); matchedStaticPath = staticPaths.find(({ params: _params }) => JSON.stringify(_params) === paramsKey); } diff --git a/yarn.lock b/yarn.lock index f46009e71fca..e08bce4e4d09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1752,7 +1752,7 @@ dependencies: "@types/node" "*" -"@types/debug@^4.0.0": +"@types/debug@^4.0.0", "@types/debug@^4.1.7": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==