From beb01050dd426231759d73e7da9ba7f56d78927d Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Thu, 2 Jan 2025 21:25:52 +0900 Subject: [PATCH] fix: add size reporting scripts --- package.json | 2 + pnpm-lock.yaml | 8 +++ scripts/report-size.ts | 110 +++++++++++++++++++++++++++++++++++++++++ scripts/size.ts | 9 +--- scripts/utils.ts | 7 +++ 5 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 scripts/report-size.ts diff --git a/package.json b/package.json index 797b3cf52..6bb013162 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "build:type": "./scripts/build.sh", "build:typed": "pnpm build core-base vue-i18n-core --withTypes", "size": "tsx ./scripts/build.ts --size && tsx ./scripts/size.ts", + "size:report": "tsx ./scripts/report-size.ts", "clean": "run-p clean:*", "clean:coverage": "rm -rf ./coverage", "clean:dist": "rm -rf ./dist ./packages/**/dist ./docs/.vitepress/dist", @@ -113,6 +114,7 @@ "jsdom": "^24.0.0", "lint-staged": "^15.2.2", "listhen": "^1.7.2", + "markdown-table": "^3.0.4", "mitata": "^1.0.20", "npm-run-all2": "^7.0.0", "opener": "^1.5.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9317f8f5..bd07c7e11 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -111,6 +111,9 @@ importers: listhen: specifier: ^1.7.2 version: 1.7.2 + markdown-table: + specifier: ^3.0.4 + version: 3.0.4 mitata: specifier: ^1.0.20 version: 1.0.20 @@ -5015,6 +5018,9 @@ packages: markdown-table@2.0.0: resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + match-casing@1.0.3: resolution: {integrity: sha512-oMyC3vUVCFbGu+M2Zxl212LPJThcaw7QxB5lFuJPQCgV/dsGBP0yZeCoLmX6CiBkoBcVbAKDJZrBpJVu0XcLMw==} @@ -12703,6 +12709,8 @@ snapshots: dependencies: repeat-string: 1.6.1 + markdown-table@3.0.4: {} + match-casing@1.0.3: {} match-index@1.0.3: diff --git a/scripts/report-size.ts b/scripts/report-size.ts new file mode 100644 index 000000000..d85d6a2d2 --- /dev/null +++ b/scripts/report-size.ts @@ -0,0 +1,110 @@ +import { markdownTable } from 'markdown-table' +import { existsSync, promises as fs } from 'node:fs' +import path from 'node:path' +import { displaySize } from './utils' + +import type { BundleReport } from './utils' + +type UsageReport = Record + +const currDir = path.resolve('temp/size') +const prevDir = path.resolve('temp/size-prev') +const sizeHeaders = ['Size', 'Gzip', 'Brotli'] + +async function rednerFiles(output: string) { + const filterFiles = (files: string[]) => + files.filter(file => file[0] !== '_' && !file.endsWith('.txt')) + + const curr = filterFiles(await fs.readdir(currDir)) + const prev = existsSync(prevDir) ? filterFiles(await fs.readdir(prevDir)) : [] + const fileList = new Set([...curr, ...prev]) + + const rows = [] + for (const file of fileList) { + const currPath = path.resolve(currDir, file) + const prevPath = path.resolve(prevDir, file) + + const curr = await importJSON(currPath) + const prev = await importJSON(prevPath) + const fileName = curr?.file || prev?.file || '' + + if (!curr) { + rows.push([`~~${fileName}~~`]) + } else { + rows.push([ + fileName, + `${displaySize(curr.size)}${getDiff(curr.size, prev?.size)}`, + `${displaySize(curr.gzip)}${getDiff(curr.gzip, prev?.gzip)}`, + `${displaySize(curr.brotli)}${getDiff(curr.brotli, prev?.brotli)}` + ]) + } + } + + output += '### Bundles\n\n' + output += markdownTable([['File', ...sizeHeaders], ...rows]) + output += '\n\n' + + return output +} + +async function importJSON(filePath: string) { + if (!existsSync(filePath)) { + return undefined + } + return (await import(filePath, { assert: { type: 'json' } })).default +} + +function getDiff(curr: number, prev: number) { + if (prev === undefined) { + return '' + } + const diff = curr - prev + if (diff === 0) { + return '' + } + const sign = diff > 0 ? '+' : '' + return ` (**${sign}${displaySize(diff)}**)` +} + +async function renderUsages(output: string) { + const curr = (await importJSON( + path.resolve(currDir, '_usages.json') + )) as UsageReport + const prev = (await importJSON( + path.resolve(prevDir, '_usages.json') + )) as UsageReport + + output += '\n### Usages\n\n' + + const data = Object.values(curr) + .map(usage => { + const prevUsage = prev?.[usage.name] + const diffSize = getDiff(usage.size, prevUsage?.size) + const diffGzipped = getDiff(usage.gzip, prevUsage?.gzip) + const diffBrotli = getDiff(usage.brotli, prevUsage?.brotli) + + return [ + usage.name, + `${displaySize(usage.size)}${diffSize}`, + `${displaySize(usage.gzip)}${diffGzipped}`, + `${displaySize(usage.brotli)}${diffBrotli}` + ] + }) + .filter(usage => !!usage) + + output += `${markdownTable([['Name', ...sizeHeaders], ...data])}\n\n` + + return output +} + +async function main() { + let output = '## Size Report\n\n' + output = await rednerFiles(output) + output = await renderUsages(output) + process.stdout.write(output) +} + +main().catch(err => { + console.error(err) + process.exit(1) +}) diff --git a/scripts/size.ts b/scripts/size.ts index fd6bacf27..75a9be142 100644 --- a/scripts/size.ts +++ b/scripts/size.ts @@ -5,16 +5,11 @@ import { fileURLToPath } from 'node:url' import pc from 'picocolors' import { displaySize, sizeTargets } from './utils' +import type { BundleReport } from './utils' + const __dirname = fileURLToPath(new URL('.', import.meta.url)) const sizeDir = path.resolve(__dirname, '../temp/size') -type BundleReport = { - name: string - size: number - gzip: number - brotli: number -} - async function main() { console.log('📏 Checking bundle sizes ...') console.log() diff --git a/scripts/utils.ts b/scripts/utils.ts index 99511fee1..d65112c1b 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -2,6 +2,13 @@ import { promises as fs } from 'node:fs' import { dirname, resolve } from 'node:path' import pc from 'picocolors' +export type BundleReport = { + name: string + size: number + gzip: number + brotli: number +} + export const targets = async () => { const packages = await fs.readdir('packages') const files = await Promise.all(