Add a tabular bundlewatch script (#41957)
Some checks are pending
BrowserStack / browserstack (push) Waiting to run
Bundlewatch / bundlewatch (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
cspell / cspell (push) Waiting to run
CSS / css (push) Waiting to run
Docs / docs (push) Waiting to run
JS Tests / JS Tests (push) Waiting to run
Lint / lint (push) Waiting to run
Release notes / update_release_draft (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run

* Script for better bundlewatch locally

* Fix linter
This commit is contained in:
Mark Otto 2025-12-21 11:16:35 -08:00 committed by GitHub
parent 2d1e26710b
commit 4b90546519
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 105 additions and 11 deletions

View File

@ -2,43 +2,43 @@
"files": [
{
"path": "./dist/css/bootstrap-grid.css",
"maxSize": "10.0 kB"
"maxSize": "9.5 kB"
},
{
"path": "./dist/css/bootstrap-grid.min.css",
"maxSize": "9.0 kB"
"maxSize": "8.5 kB"
},
{
"path": "./dist/css/bootstrap-reboot.css",
"maxSize": "5.5 kB"
"maxSize": "5.25 kB"
},
{
"path": "./dist/css/bootstrap-reboot.min.css",
"maxSize": "4.5 kB"
"maxSize": "4.25 kB"
},
{
"path": "./dist/css/bootstrap-utilities.css",
"maxSize": "15.25 kB"
"maxSize": "14.5 kB"
},
{
"path": "./dist/css/bootstrap-utilities.min.css",
"maxSize": "13.5 kB"
"maxSize": "12.75 kB"
},
{
"path": "./dist/css/bootstrap.css",
"maxSize": "37.75 kB"
"maxSize": "35.5 kB"
},
{
"path": "./dist/css/bootstrap.min.css",
"maxSize": "33.75 kB"
"maxSize": "32.0 kB"
},
{
"path": "./dist/js/bootstrap.bundle.js",
"maxSize": "44.0 kB"
"maxSize": "43.5 kB"
},
{
"path": "./dist/js/bootstrap.bundle.min.js",
"maxSize": "23.5 kB"
"maxSize": "22.5 kB"
},
{
"path": "./dist/js/bootstrap.esm.js",
@ -50,7 +50,7 @@
},
{
"path": "./dist/js/bootstrap.js",
"maxSize": "30.5 kB"
"maxSize": "30.25 kB"
},
{
"path": "./dist/js/bootstrap.min.js",

View File

@ -0,0 +1,93 @@
#!/usr/bin/env node
import { execSync } from 'node:child_process'
// Run bundlewatch and capture output
let stdout
let exitCode = 0
try {
stdout = execSync('npx bundlewatch --config .bundlewatch.config.json', {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe']
})
} catch (error) {
stdout = error.stdout || ''
exitCode = error.status || 1
}
// Parse lines that contain PASS or FAIL
const lines = stdout.split('\n').filter(l => l.startsWith('PASS') || l.startsWith('FAIL'))
if (lines.length === 0) {
console.log(stdout)
process.exit(exitCode)
}
// Parse size string to number (KB)
const parseSize = str => Number.parseFloat(str.replace('KB', ''))
// Calculate column widths and headroom
const rows = lines.map(line => {
const match = line.match(/(PASS|FAIL)\s+(.+?):\s+([\d.]+KB)\s+([<>])\s+([\d.]+KB)/)
if (match) {
const sizeNum = parseSize(match[3])
const maxNum = parseSize(match[5])
const headroomNum = maxNum - sizeNum
const headroom = `${headroomNum.toFixed(2)}KB`
return {
status: match[1],
file: match[2],
size: match[3],
max: match[5],
headroomNum,
headroom: match[1] === 'PASS' ? `+${headroom}` : `-${Math.abs(headroomNum).toFixed(2)}KB`
}
}
return null
}).filter(Boolean)
const maxFileLen = Math.max(...rows.map(r => r.file.length), 4)
const maxSizeLen = Math.max(...rows.map(r => r.size.length), 4)
const maxMaxLen = Math.max(...rows.map(r => r.max.length), 3)
const maxHeadroomLen = Math.max(...rows.map(r => r.headroom.length), 8)
// Build table
const hr = `+-${'-'.repeat(maxFileLen)}-+-${'-'.repeat(maxSizeLen)}-+-${'-'.repeat(maxMaxLen)}-+-${'-'.repeat(maxHeadroomLen)}-+`
console.log('')
console.log('bundlewatch results')
console.log(hr)
console.log(`| ${'File'.padEnd(maxFileLen)} | ${'Size'.padStart(maxSizeLen)} | ${'Max'.padStart(maxMaxLen)} | ${'Headroom'.padStart(maxHeadroomLen)} |`)
console.log(hr)
const green = '\u001B[32m'
const red = '\u001B[31m'
const reset = '\u001B[0m'
for (const row of rows) {
const sizeColor = row.status === 'PASS' ? green : red
const coloredSize = `${sizeColor}${row.size.padStart(maxSizeLen)}${reset}`
const headroomColor = row.headroomNum > 0.25 ? red : ''
const headroomReset = row.headroomNum > 0.25 ? reset : ''
const coloredHeadroom = `${headroomColor}${row.headroom.padStart(maxHeadroomLen)}${headroomReset}`
console.log(`| ${row.file.padEnd(maxFileLen)} | ${coloredSize} | ${row.max.padStart(maxMaxLen)} | ${coloredHeadroom} |`)
}
console.log(hr)
// Summary
const passed = rows.filter(r => r.status === 'PASS').length
const failed = rows.filter(r => r.status === 'FAIL').length
console.log('')
if (failed > 0) {
console.log(`\u001B[31mbundlewatch FAIL\u001B[0m - ${passed} passed, ${failed} failed`)
} else {
console.log(`\u001B[32mbundlewatch PASS\u001B[0m - ${passed}/${rows.length} files within limits`)
}
console.log('')
process.exit(exitCode)

View File

@ -41,6 +41,7 @@
"scripts": {
"start": "npm-run-all --parallel watch docs-serve",
"bundlewatch": "bundlewatch --config .bundlewatch.config.json",
"bundlewatch:table": "node build/bundlewatch-table.mjs",
"css": "npm-run-all css-compile css-prefix css-minify css-docs",
"css-compile": "sass --style expanded --source-map --embed-sources --no-error-css scss/bootstrap.scss:dist/css/bootstrap.css scss/bootstrap-grid.scss:dist/css/bootstrap-grid.css scss/bootstrap-reboot.scss:dist/css/bootstrap-reboot.css scss/bootstrap-utilities.scss:dist/css/bootstrap-utilities.css",
"css-docs": "node build/generate-utilities-json.mjs",