Skip to content

Commit 727b578

Browse files
Harden build failures and dev CSS placeholders
Propagate webpack build failures via explicit exit codes so production builds fail loudly. Derive dev CSS placeholders from the computed output list to avoid hardcoded filenames.
1 parent 11b4531 commit 727b578

1 file changed

Lines changed: 51 additions & 17 deletions

File tree

build.mjs

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -399,21 +399,34 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, sourceBuil
399399
if (isProduction) {
400400
// Ensure compiler is properly closed after production runs
401401
compiler.run((err, stats) => {
402+
const hasErrors = !!(
403+
err ||
404+
(stats && typeof stats.hasErrors === 'function' && stats.hasErrors())
405+
)
406+
let callbackFailed = false
402407
const finishClose = () =>
403408
compiler.close((closeErr) => {
404409
if (closeErr) {
405410
console.error('Error closing compiler:', closeErr)
406411
process.exitCode = 1
407412
}
413+
if (hasErrors || callbackFailed) {
414+
process.exitCode = 1
415+
}
408416
})
409417
try {
410418
const ret = callback(err, stats)
411419
if (ret && typeof ret.then === 'function') {
412-
ret.then(finishClose, finishClose)
420+
ret.then(finishClose, () => {
421+
callbackFailed = true
422+
finishClose()
423+
})
413424
} else {
414425
finishClose()
415426
}
416-
} catch (_) {
427+
} catch (err) {
428+
console.error('[build] Callback error:', err)
429+
callbackFailed = true
417430
finishClose()
418431
}
419432
})
@@ -510,18 +523,19 @@ async function copyFiles(entryPoints, targetDir) {
510523
}
511524

512525
// In development, create placeholder CSS and sourcemap files to avoid 404 noise
513-
async function ensureDevCssPlaceholders(targetDir) {
514-
if (isProduction) return
515-
const cssFiles = [path.join(targetDir, 'popup.css'), path.join(targetDir, 'content-script.css')]
516-
for (const cssPath of cssFiles) {
517-
if (!(await fs.pathExists(cssPath))) {
518-
await fs.outputFile(cssPath, '/* dev placeholder */\n')
519-
}
520-
const mapPath = `${cssPath}.map`
521-
if (!(await fs.pathExists(mapPath))) {
522-
await fs.outputFile(mapPath, '{"version":3,"sources":[],"mappings":"","names":[]}')
523-
}
524-
}
526+
async function ensureDevCssPlaceholders(cssFiles) {
527+
if (isProduction || cssFiles.length === 0) return
528+
await Promise.all(
529+
cssFiles.map(async (cssPath) => {
530+
if (!(await fs.pathExists(cssPath))) {
531+
await fs.outputFile(cssPath, '/* dev placeholder */\n')
532+
}
533+
const mapPath = `${cssPath}.map`
534+
if (!(await fs.pathExists(mapPath))) {
535+
await fs.outputFile(mapPath, '{"version":3,"sources":[],"mappings":"","names":[]}')
536+
}
537+
}),
538+
)
525539
}
526540

527541
async function finishOutput(outputDirSuffix, sourceBuildDir = outdir) {
@@ -560,7 +574,15 @@ async function finishOutput(outputDirSuffix, sourceBuildDir = outdir) {
560574
[...commonFiles, { src: 'src/manifest.json', dst: 'manifest.json' }],
561575
chromiumOutputDir,
562576
)
563-
await ensureDevCssPlaceholders(chromiumOutputDir)
577+
await ensureDevCssPlaceholders(
578+
Array.from(
579+
new Set(
580+
commonFiles
581+
.filter((file) => file.dst.endsWith('.css'))
582+
.map((file) => path.join(chromiumOutputDir, file.dst)),
583+
),
584+
),
585+
)
564586
if (isProduction) await zipFolder(chromiumOutputDir)
565587

566588
// firefox
@@ -569,7 +591,15 @@ async function finishOutput(outputDirSuffix, sourceBuildDir = outdir) {
569591
[...commonFiles, { src: 'src/manifest.v2.json', dst: 'manifest.json' }],
570592
firefoxOutputDir,
571593
)
572-
await ensureDevCssPlaceholders(firefoxOutputDir)
594+
await ensureDevCssPlaceholders(
595+
Array.from(
596+
new Set(
597+
commonFiles
598+
.filter((file) => file.dst.endsWith('.css'))
599+
.map((file) => path.join(firefoxOutputDir, file.dst)),
600+
),
601+
),
602+
)
573603
if (isProduction) await zipFolder(firefoxOutputDir)
574604
}
575605

@@ -605,10 +635,14 @@ async function build() {
605635
const tmpMin = `${outdir}/.tmp-min`
606636
try {
607637
if (parallelBuild) {
608-
await Promise.all([
638+
const results = await Promise.allSettled([
609639
createWebpackBuildPromise(true, true, true, tmpMin, '-without-katex-and-tiktoken'),
610640
createWebpackBuildPromise(false, false, false, tmpFull, ''),
611641
])
642+
const failed = results.find((result) => result.status === 'rejected')
643+
if (failed) {
644+
throw failed.reason
645+
}
612646
} else {
613647
await createWebpackBuildPromise(true, true, true, tmpMin, '-without-katex-and-tiktoken')
614648
await createWebpackBuildPromise(false, false, false, tmpFull, '')

0 commit comments

Comments
 (0)