(_options, bundle)
| 30 | const bundleStatsPlugin = (): PluginOption => ({ |
| 31 | name: "boringstack-bundle-stats", |
| 32 | generateBundle(_options, bundle) { |
| 33 | const assets = Object.entries(bundle) |
| 34 | .map(([fileName, output]) => { |
| 35 | const source = |
| 36 | output.type === "chunk" ? output.code : toSourceString(output.source); |
| 37 | const bytes = Buffer.byteLength(source, "utf8"); |
| 38 | |
| 39 | return { |
| 40 | bytes, |
| 41 | brotliBytes: brotliCompressSync(source).byteLength, |
| 42 | fileName, |
| 43 | gzipBytes: gzipSync(source).byteLength, |
| 44 | kind: output.type |
| 45 | }; |
| 46 | }) |
| 47 | .sort((a, b) => b.bytes - a.bytes); |
| 48 | const totalBytes = assets.reduce((sum, asset) => sum + asset.bytes, 0); |
| 49 | const rows = assets |
| 50 | .map( |
| 51 | (asset) => ` |
| 52 | <tr> |
| 53 | <td>${escapeHtml(asset.fileName)}</td> |
| 54 | <td>${escapeHtml(asset.kind)}</td> |
| 55 | <td>${formatBytes(asset.bytes)}</td> |
| 56 | <td>${formatBytes(asset.gzipBytes)}</td> |
| 57 | <td>${formatBytes(asset.brotliBytes)}</td> |
| 58 | </tr>` |
| 59 | ) |
| 60 | .join(""); |
| 61 | const html = `<!doctype html> |
| 62 | <html lang="en"> |
| 63 | <head> |
| 64 | <meta charset="utf-8" /> |
| 65 | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| 66 | <title>BoringStack bundle stats</title> |
| 67 | <style> |
| 68 | body { color: #101828; font-family: Inter, ui-sans-serif, system-ui, sans-serif; margin: 2rem; } |
| 69 | table { border-collapse: collapse; width: 100%; } |
| 70 | th, td { border-bottom: 1px solid #eaecf0; padding: 0.625rem 0.75rem; text-align: left; } |
| 71 | th { background: #f9fafb; font-size: 0.8125rem; text-transform: uppercase; } |
| 72 | td:nth-child(n + 3) { font-variant-numeric: tabular-nums; white-space: nowrap; } |
| 73 | </style> |
| 74 | </head> |
| 75 | <body> |
| 76 | <h1>BoringStack bundle stats</h1> |
| 77 | <p>${assets.length} emitted assets, ${formatBytes(totalBytes)} raw total.</p> |
| 78 | <table> |
| 79 | <thead> |
| 80 | <tr> |
| 81 | <th>Asset</th> |
| 82 | <th>Type</th> |
| 83 | <th>Raw</th> |
| 84 | <th>Gzip</th> |
| 85 | <th>Brotli</th> |
| 86 | </tr> |
| 87 | </thead> |
| 88 | <tbody>${rows}</tbody> |
| 89 | </table> |
nothing calls this directly
no test coverage detected