Skip to content

Commit

Permalink
fix(check): filter and print esbuild messages nicely
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard committed Jul 14, 2023
1 parent 3feaa98 commit f0d6501
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 78 deletions.
160 changes: 87 additions & 73 deletions src/node/check.ts
@@ -1,9 +1,10 @@
import esbuild, {BuildFailure} from 'esbuild'
import path from 'path'

import {createConsoleSpy} from './consoleSpy'
import {getPkgExtMap, loadConfig, loadPkgWithReporting} from './core'
import {fileExists} from './fileExists'
import {createLogger} from './logger'
import {createLogger, Logger} from './logger'
import {printPackageTree} from './printPackageTree'
import {resolveBuildContext} from './resolveBuildContext'

Expand Down Expand Up @@ -52,91 +53,104 @@ export async function check(options: {
}

// Check if the files are resolved
const _paths: {require: string[]; import: string[]} = {
const exportPaths: {require: string[]; import: string[]} = {
require: [],
import: [],
}

for (const exp of Object.values(ctx.exports || {})) {
if (!exp._exported) continue
if (exp.require) _paths.require.push(exp.require)
if (exp.import) _paths.import.push(exp.import)
if (exp.require) exportPaths.require.push(exp.require)
if (exp.import) exportPaths.import.push(exp.import)
}

const external = Object.keys(pkg.dependencies || {}).concat(
Object.keys(pkg.devDependencies || {})
)
const external = [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.devDependencies || {}),
]

if (_paths.import.length) {
const code = _paths.import.map((id) => `import('${id}')`).join('\n')

try {
const esbuildResult = await esbuild.build({
external,
stdin: {
contents: code,
loader: 'js',
resolveDir: cwd,
},
format: 'esm',
bundle: true,
logLevel: 'silent',
// otherwise output maps to stdout as we're using stdin
outfile: '/dev/null',
platform: 'node',
})

if (esbuildResult.warnings.length > 0) {
logger.warn(...esbuildResult.warnings)
}
} catch (err) {
const {errors} = err as BuildFailure

for (const _err of errors) {
if (_err.location) {
logger.error(_err.detail || _err.text)
logger.error(`${_err.location.line} | ${_err.location.lineText}`)
logger.error(
'in',
`./${_err.location.file}:${_err.location.line}:${_err.location.column}`
)
} else {
logger.error(_err.detail || _err.text)
}

logger.log()
}

process.exit(1)
}
const consoleSpy = createConsoleSpy()

if (exportPaths.import.length) {
checkExports(exportPaths.import, {cwd, external, format: 'esm', logger})
}

if (_paths.require.length) {
const code = _paths.require.map((id) => `require('${id}')`).join('\n')

const esbuildResult = await esbuild.build({
external,
stdin: {
contents: code,
loader: 'js',
resolveDir: cwd,
},
format: 'cjs',
bundle: true,
// otherwise output maps to stdout as we're using stdin
outfile: '/dev/null',
platform: 'node',
})

if (esbuildResult.errors.length > 0) {
// throw new Error(esbuildResult.errors.join(', '))
logger.error(esbuildResult.errors.join(', '))
process.exit(1)
}
if (exportPaths.require.length) {
checkExports(exportPaths.require, {cwd, external, format: 'cjs', logger})
}

if (esbuildResult.warnings.length > 0) {
logger.warn(...esbuildResult.warnings)
consoleSpy.restore()
}
}

async function checkExports(
exportPaths: string[],
options: {cwd: string; external: string[]; format: 'esm' | 'cjs'; logger: Logger}
) {
const {cwd, external, format, logger} = options

const code = exportPaths
.map((id) => (format ? `import('${id}');` : `require('${id}');`))
.join('\n')

try {
const esbuildResult = await esbuild.build({
bundle: true,
external,
format,
logLevel: 'silent',
// otherwise output maps to stdout as we're using stdin
outfile: '/dev/null',
platform: 'node',
stdin: {
contents: code,
loader: 'js',
resolveDir: cwd,
},
})

if (esbuildResult.errors.length > 0) {
for (const msg of esbuildResult.errors) {
printEsbuildMessage(logger.warn, msg)

logger.log()
}

process.exit(1)
}

const esbuildWarnings = esbuildResult.warnings.filter((msg) => {
!(msg.detail || msg.text).includes(`does not affect esbuild's own target setting`)
})

for (const msg of esbuildWarnings) {
printEsbuildMessage(logger.warn, msg)

logger.log()
}
} catch (err) {
const {errors} = err as BuildFailure

for (const msg of errors) {
printEsbuildMessage(logger.error, msg)

logger.log()
}

process.exit(1)
}
}

function printEsbuildMessage(log: (...args: unknown[]) => void, msg: esbuild.Message) {
if (msg.location) {
log(
[
`${msg.detail || msg.text}\n`,
`${msg.location.line} | ${msg.location.lineText}\n`,
`in ./${msg.location.file}:${msg.location.line}:${msg.location.column}`,
].join('')
)
} else {
log(msg.detail || msg.text)
}
}
Expand Up @@ -11,10 +11,10 @@ export interface ConsoleSpy {
restore: () => void
}

export function createConsoleSpy(options: {
onRestored: (messages: ConsoleSpyMsg[]) => void
export function createConsoleSpy(options?: {
onRestored?: (messages: ConsoleSpyMsg[]) => void
}): ConsoleSpy {
const {onRestored} = options
const {onRestored} = options || {}

const original = {
log: console.log,
Expand All @@ -35,7 +35,7 @@ export function createConsoleSpy(options: {
console.warn = original.warn
console.error = original.error

onRestored(messages)
onRestored?.(messages)
},
}
}
2 changes: 1 addition & 1 deletion src/node/tasks/rollup/rollupTask.ts
Expand Up @@ -3,9 +3,9 @@ import path from 'path'
import {rollup} from 'rollup'
import {Observable} from 'rxjs'

import {createConsoleSpy} from '../../consoleSpy'
import {BuildContext} from '../../core'
import {RollupTask, TaskHandler} from '../types'
import {createConsoleSpy} from './consoleSpy'
import {resolveRollupConfig} from './resolveRollupConfig'

/** @internal */
Expand Down

0 comments on commit f0d6501

Please sign in to comment.