From cc0e851e98fb6cd6f5ef5b302a902b66db4deca5 Mon Sep 17 00:00:00 2001 From: Luke Edwards <4302197+brisbaneg2@users.noreply.github.com> Date: Thu, 25 Mar 2021 11:56:33 -0700 Subject: [PATCH] feat: customize `esbuild` error/warning formatting - see: https://github.com/evanw/esbuild/issues/1058 --- package.json | 2 +- src/commands/build.ts | 12 +++++------- src/log.ts | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 53be64e..9d870cd 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test": "tsc --noEmit" }, "dependencies": { - "esbuild": "^0.10.0", + "esbuild": "^0.10.1", "httpie": "^1.1.2", "kleur": "^4.0.0", "klona": "^2.0.0", diff --git a/src/commands/build.ts b/src/commands/build.ts index 1365b5d..8e6d4c6 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -13,7 +13,7 @@ const defaults: BuildOptions = { sourcemap: false, outfile: '', entryPoints: [''], - logLevel: 'warning', // render warnings & errors + logLevel: 'silent', // errros/warnings & handled manually resolveExtensions: ['.tsx', '.ts', '.jsx', '.mjs', '.js', '.json'], mainFields: ['worker', 'browser', 'module', 'jsnext', 'main'], conditions: ['worker', 'browser', 'import', 'production'], @@ -68,13 +68,10 @@ export default async function (src: string | void, output: string | void, opts: try { var now = Date.now(); - await esbuild.build(config); + var result = await esbuild.build(config); } catch (err) { - // TODO: render errors manually (`chore/errors` branch) - // @see https://github.com/evanw/esbuild/issues/1058 - let count = (err as BuildFailure).errors.length; - let suffix = count === 1 ? 'error' : 'errors'; - return log.error(`Build failed with ${colors.underline(count)} ${suffix}!`); + let { errors } = err as BuildFailure; + return await log.messages(errors, true); } await utils.write( @@ -83,6 +80,7 @@ export default async function (src: string | void, output: string | void, opts: ); console.log(arrow + name + log.time(Date.now() - now)); + await log.messages(result.warnings); } log.success(`Build complete!\nYour worker${sfx} ${items.length === 1 ? 'is' : 'are'} ready for deployment 🎉`); diff --git a/src/log.ts b/src/log.ts index 7b3a716..bda96fe 100644 --- a/src/log.ts +++ b/src/log.ts @@ -1,4 +1,5 @@ import colors from 'kleur'; +import type { Message } from 'esbuild'; export const ARROW = ' ~> '; export const SPACER = ' '.repeat(6); @@ -34,3 +35,39 @@ export function item(name: string, delta?: number, isAdd?: boolean) { else if (isAdd != null) (sym='-', fn=colors.red().dim); console.log( fn(SPACER + sym + ` "${name}"`) + text); } + +// format esbuild errors/warnings +export async function messages(arr: Message[], isError?: boolean) { + let i=0, count=arr.length; + if (count === i) return; + + const esbuild = await import('esbuild'); + + let frames = await esbuild.formatMessages(arr, { + terminalWidth: process.stdout.columns, + kind: isError ? 'error' : 'warning', + color: colors.enabled, + }); + + let rgx = /\x1b\[32m/g; // replace ANSI green + let color = isError ? '\u001b[31m' : '\u001b[33m'; // red|yellow + let fmt = isError ? colors.red : colors.yellow; + + let output = `Build ${isError ? 'failed' : 'finished'} with`; + output += ' ' + colors.underline(count) + ' '; + output += isError ? 'error' : 'warning'; + output += count === 1 ? ':' : 's:'; + output += '\n\n'; + + for (; i < count; i++) { + output += colors.bold().inverse( fmt(' ' + arr[i].location.file + ' ')) + ' ' + arr[i].text; + output += frames[i].substring(frames[i].indexOf('\n')).replace(rgx, color); + } + + i = output.length; + if (output[--i] === '\n') { + output = output.substring(0, i); + } + + (isError ? error : warn)(output); +}