Skip to content

Commit a484961

Browse files
committed
feat: compare size
1 parent e6ef1c9 commit a484961

File tree

5 files changed

+161
-15
lines changed

5 files changed

+161
-15
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,6 @@ jobs:
149149
name: size-report
150150
path: temp/size-prev
151151

152-
- name: test
153-
run: ls -l temp
152+
- name: Compare size
153+
run: node scripts/compare-size.js
154154
if: ${{ success() }}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@rollup/plugin-node-resolve": "^15.0.1",
6464
"@rollup/plugin-replace": "^5.0.2",
6565
"@rollup/plugin-terser": "^0.4.0",
66+
"@sxzz/export-size": "^0.6.0",
6667
"@types/hash-sum": "^1.0.0",
6768
"@types/node": "^16.4.7",
6869
"@typescript-eslint/parser": "^5.56.0",
@@ -77,11 +78,11 @@
7778
"eslint-plugin-jest": "^27.2.1",
7879
"estree-walker": "^2.0.2",
7980
"execa": "^4.0.2",
80-
"@sxzz/export-size": "^0.6.0",
8181
"jsdom": "^21.1.0",
8282
"lint-staged": "^10.2.10",
8383
"lodash": "^4.17.15",
8484
"magic-string": "^0.30.0",
85+
"markdown-table": "^3.0.3",
8586
"marked": "^4.0.10",
8687
"minimist": "^1.2.0",
8788
"npm-run-all": "^4.1.5",

pnpm-lock.yaml

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/compare-size.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// @ts-check
2+
import path from 'node:path'
3+
import { markdownTable } from 'markdown-table'
4+
import prettyBytes from 'pretty-bytes'
5+
import { readFile, readdir } from 'node:fs/promises'
6+
import { existsSync } from 'node:fs'
7+
8+
const currDir = path.resolve('temp/size')
9+
const prevDir = path.resolve('temp/size-prev')
10+
let output = '## Compare Size\n'
11+
12+
run()
13+
14+
async function run() {
15+
await processExports()
16+
await renderBaseline()
17+
await renderFiles()
18+
19+
process.stdout.write(output)
20+
}
21+
22+
async function renderFiles() {
23+
/**
24+
*
25+
* @param {string[]} files
26+
* @returns {string[]}
27+
*/
28+
const filterFiles = files => files.filter(file => !file.startsWith('_'))
29+
30+
const curr = filterFiles(await readdir(currDir))
31+
const prev = filterFiles(await readdir(prevDir))
32+
const fileList = new Set([...curr, ...prev])
33+
34+
/** @type string[][] */
35+
const rows = []
36+
for (const file of fileList) {
37+
const currPath = path.resolve(currDir, file)
38+
const prevPath = path.resolve(prevDir, file)
39+
40+
let curr
41+
if (existsSync(currPath)) curr = await importJSON(currPath)
42+
let prev
43+
if (existsSync(prevPath)) prev = await importJSON(prevPath)
44+
45+
const fileName = curr?.file || prev?.file
46+
47+
if (!curr) {
48+
rows.push([`~~${fileName}~~`])
49+
} else
50+
rows.push([
51+
fileName,
52+
`${prettyBytes(curr.size)}${getDiff(curr.size, prev?.size)}`,
53+
`${prettyBytes(curr.gzip)}${getDiff(curr.gzip, prev?.gzip)}`,
54+
`${prettyBytes(curr.brotli)}${getDiff(curr.brotli, prev?.brotli)}`
55+
])
56+
}
57+
58+
output += '### Bundles\n\n'
59+
output += markdownTable([['File', 'Size', 'Gzip', 'Brotli'], ...rows])
60+
output += '\n\n'
61+
}
62+
63+
async function renderBaseline() {
64+
const curr = await importJSON(path.resolve(currDir, '_baseline.json'))
65+
const prev = await importJSON(path.resolve(prevDir, '_baseline.json'))
66+
output += `### Baseline\n\n`
67+
output += markdownTable([
68+
['Size', 'Gzip', 'Brotli'],
69+
[
70+
`${prettyBytes(curr.size)}${getDiff(curr.size, prev?.size)}`,
71+
`${prettyBytes(curr.gzip)}${getDiff(curr.gzip, prev?.gzip)}`,
72+
`${prettyBytes(curr.brotli)}${getDiff(curr.brotli, prev?.brotli)}`
73+
]
74+
])
75+
output += '\n\n'
76+
}
77+
78+
async function processExports() {
79+
const curr = await importJSON(path.resolve(currDir, '_exports.json'))
80+
const prev = await importJSON(path.resolve(prevDir, '_exports.json'))
81+
output += '\n### Exports\n\n'
82+
output += renderExports(curr, prev)
83+
output += `\n\n<details>\n<summary>Show full exports</summary>\n\n${renderExports(
84+
curr
85+
)}\n\n</details>\n\n`
86+
}
87+
88+
/** @typedef {Record<string, import('@sxzz/export-size').ExportsInfo>} ExportMap */
89+
90+
/**
91+
*
92+
* @param {ExportMap} exports
93+
* @param {ExportMap} [prev]
94+
* @returns
95+
*/
96+
function renderExports(exports, prev) {
97+
const data = Object.entries(exports)
98+
.map(
99+
/** @returns {any} */
100+
([key, exp]) => {
101+
const prevExport = prev?.[key]
102+
const diffBundled = getDiff(exp.bundled, prevExport?.bundled)
103+
const diffMinified = getDiff(exp.minified, prevExport?.minified)
104+
const diffMinzipped = getDiff(exp.minzipped, prevExport?.minzipped)
105+
if (prev && !diffBundled && !diffMinified && !diffMinzipped) {
106+
return
107+
}
108+
109+
return [
110+
exp.name,
111+
`${prettyBytes(exp.bundled)}${diffBundled}`,
112+
`${prettyBytes(exp.minified)}${diffMinified}`,
113+
`${prettyBytes(exp.minzipped)}${diffMinzipped}`
114+
]
115+
}
116+
)
117+
.filter(Boolean)
118+
if (data.length === 0) return 'No changes'
119+
return markdownTable([['Name', 'Size', 'Minified', 'Brotli'], ...data])
120+
}
121+
122+
/**
123+
* @param {string} path
124+
*/
125+
async function importJSON(path) {
126+
return (await import(path, { assert: { type: 'json' } })).default
127+
}
128+
129+
/**
130+
*
131+
* @param {number} curr
132+
* @param {number} [prev]
133+
*/
134+
function getDiff(curr, prev) {
135+
if (prev === undefined) return ''
136+
const diff = curr - prev
137+
if (diff === 0) return ''
138+
const sign = diff > 0 ? '+' : ''
139+
return ` (**${sign}${prettyBytes(diff)}**)`
140+
}

scripts/export-size.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ async function main() {
1414
bundler: 'esbuild',
1515
output: false
1616
})
17+
const functions = Object.fromEntries(
18+
exports.map(exp => {
19+
return [exp.name, { ...exp, file: path.basename(exp.path) }]
20+
})
21+
)
1722
await mkdir(sizeDir, { recursive: true })
1823
await writeFile(
1924
path.resolve(sizeDir, '_exports.json'),
20-
JSON.stringify(exports, null, 2),
25+
JSON.stringify(functions, null, 2),
2126
'utf-8'
2227
)
2328
}

0 commit comments

Comments
 (0)