mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
ci(ci): add bundle size reporting workflow (#511)
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
name: Bundle Size
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
size:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install and build PR
|
||||
run: pnpm install && pnpm build:packages
|
||||
|
||||
- name: Measure PR bundle size
|
||||
run: pnpm -w exec size-limit --json > /tmp/pr-size.json
|
||||
|
||||
- name: Measure base bundle size
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }} --depth=1
|
||||
git checkout -f FETCH_HEAD
|
||||
|
||||
pnpm install
|
||||
|
||||
if [ -f .size-limit.json ]; then
|
||||
pnpm build:packages
|
||||
pnpm -w exec size-limit --json > /tmp/base-size.json
|
||||
else
|
||||
echo '[]' > /tmp/base-size.json
|
||||
fi
|
||||
|
||||
- name: Report
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
const pr = JSON.parse(fs.readFileSync('/tmp/pr-size.json', 'utf8'));
|
||||
const base = JSON.parse(fs.readFileSync('/tmp/base-size.json', 'utf8'));
|
||||
|
||||
const baseMap = Object.fromEntries(base.map(e => [e.name, e.size]));
|
||||
|
||||
function formatBytes(bytes) {
|
||||
if (bytes < 1024) return `${bytes} B`;
|
||||
return `${(bytes / 1024).toFixed(2)} kB`;
|
||||
}
|
||||
|
||||
function formatDelta(current, previous) {
|
||||
if (previous === undefined) return '—';
|
||||
const diff = current - previous;
|
||||
if (diff === 0) return '0 B';
|
||||
const sign = diff > 0 ? '+' : '';
|
||||
const pct = ((diff / previous) * 100).toFixed(1);
|
||||
return `${sign}${formatBytes(diff)} (${sign}${pct}%)`;
|
||||
}
|
||||
|
||||
function statusIcon(current, previous) {
|
||||
if (previous === undefined) return '🆕';
|
||||
const diff = current - previous;
|
||||
if (diff === 0) return '✅';
|
||||
if (diff < 0) return '🔽';
|
||||
const pct = (diff / previous) * 100;
|
||||
return pct > 10 ? '🔴' : '🔺';
|
||||
}
|
||||
|
||||
const rows = pr.map(entry => {
|
||||
const prev = baseMap[entry.name];
|
||||
return `| ${entry.name} | ${prev !== undefined ? formatBytes(prev) : '—'} | ${formatBytes(entry.size)} | ${formatDelta(entry.size, prev)} | ${statusIcon(entry.size, prev)} |`;
|
||||
});
|
||||
|
||||
const total = pr.reduce((sum, e) => sum + e.size, 0);
|
||||
const baseTotal = base.reduce((sum, e) => sum + e.size, 0);
|
||||
|
||||
const marker = '<!-- bundle-size-report -->';
|
||||
const body = [
|
||||
marker,
|
||||
'### 📦 Bundle Size Report',
|
||||
'',
|
||||
'| Package | Base | PR | Delta | |',
|
||||
'|---|---|---|---|---|',
|
||||
...rows,
|
||||
`| **Total** | **${base.length ? formatBytes(baseTotal) : '—'}** | **${formatBytes(total)}** | **${base.length ? formatDelta(total, baseTotal) : '—'}** | |`,
|
||||
'',
|
||||
'<details>',
|
||||
'<summary>ℹ️ How to interpret</summary>',
|
||||
'',
|
||||
'Sizes are minified + brotli compressed, measured via [size-limit](https://github.com/ai/size-limit) with esbuild tree-shaking.',
|
||||
'',
|
||||
'| Icon | Meaning |',
|
||||
'|---|---|',
|
||||
'| ✅ | No change |',
|
||||
'| 🔺 | Size increased ≤ 10% |',
|
||||
'| 🔴 | Size increased > 10% |',
|
||||
'| 🔽 | Size decreased |',
|
||||
'| 🆕 | New entry (no baseline) |',
|
||||
'',
|
||||
'Run `pnpm size` locally to check current sizes.',
|
||||
'</details>',
|
||||
].join('\n');
|
||||
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
});
|
||||
|
||||
const existing = comments.find(c => c.body?.startsWith(marker));
|
||||
|
||||
if (existing) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: existing.id,
|
||||
body,
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"name": "@videojs/store",
|
||||
"path": "packages/store/dist/default/index.js",
|
||||
"import": "*"
|
||||
},
|
||||
{
|
||||
"name": "@videojs/store/lit",
|
||||
"path": "packages/store/dist/default/lit.js",
|
||||
"import": "*"
|
||||
},
|
||||
{
|
||||
"name": "@videojs/store/react",
|
||||
"path": "packages/store/dist/default/react.js",
|
||||
"import": "*"
|
||||
},
|
||||
{
|
||||
"name": "@videojs/core",
|
||||
"path": "packages/core/dist/default/index.js",
|
||||
"import": "*"
|
||||
},
|
||||
{
|
||||
"name": "@videojs/core/dom",
|
||||
"path": "packages/core/dist/default/dom.js",
|
||||
"import": "*"
|
||||
},
|
||||
{
|
||||
"name": "@videojs/react",
|
||||
"path": "packages/react/dist/default/index.js",
|
||||
"import": "*"
|
||||
},
|
||||
{
|
||||
"name": "@videojs/html",
|
||||
"path": "packages/html/dist/default/index.js",
|
||||
"import": "*"
|
||||
}
|
||||
]
|
||||
@@ -30,10 +30,12 @@
|
||||
"lint:fix:file": "biome check --write",
|
||||
"link:opencode": "[ -e .opencode ] || ln -s .claude .opencode",
|
||||
"link:agents": "[ -e AGENTS.md ] || ln -s CLAUDE.md AGENTS.md; [ -e agents ] || ln -s .claude agents",
|
||||
"size": "size-limit",
|
||||
"test": "turbo run test",
|
||||
"typecheck": "tsc --build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@size-limit/preset-small-lib": "^12.0.0",
|
||||
"@biomejs/biome": "^2.3.11",
|
||||
"@commitlint/cli": "^20.1.0",
|
||||
"@commitlint/config-conventional": "^20.0.0",
|
||||
@@ -43,6 +45,7 @@
|
||||
"react": "^18.0.0",
|
||||
"react-compiler-runtime": "^1.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"size-limit": "^12.0.0",
|
||||
"simple-git-hooks": "^2.13.1",
|
||||
"tsx": "^4.21.0",
|
||||
"turbo": "^2.5.8",
|
||||
|
||||
Generated
+85
@@ -20,6 +20,9 @@ importers:
|
||||
'@commitlint/format':
|
||||
specifier: ^20.0.0
|
||||
version: 20.2.0
|
||||
'@size-limit/preset-small-lib':
|
||||
specifier: ^12.0.0
|
||||
version: 12.0.0(size-limit@12.0.0(jiti@2.6.1))
|
||||
'@types/node':
|
||||
specifier: ^22.18.6
|
||||
version: 22.19.3
|
||||
@@ -38,6 +41,9 @@ importers:
|
||||
simple-git-hooks:
|
||||
specifier: ^2.13.1
|
||||
version: 2.13.1
|
||||
size-limit:
|
||||
specifier: ^12.0.0
|
||||
version: 12.0.0(jiti@2.6.1)
|
||||
tsx:
|
||||
specifier: ^4.21.0
|
||||
version: 4.21.0
|
||||
@@ -2500,6 +2506,23 @@ packages:
|
||||
'@shikijs/vscode-textmate@10.0.2':
|
||||
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
|
||||
|
||||
'@size-limit/esbuild@12.0.0':
|
||||
resolution: {integrity: sha512-r9i+HrtunIu7wAPtqD3t4DqfYin3kxPoMAv8cidkzlCS69IYCe3EG2UbQa10AdvQyaHTEK+MPkr9ifUd3W29og==}
|
||||
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
peerDependencies:
|
||||
size-limit: 12.0.0
|
||||
|
||||
'@size-limit/file@12.0.0':
|
||||
resolution: {integrity: sha512-OzKYpDzWJ2jo6cAIzVsaPuvzZTmMLDoVCViEvsctmImxpXzwJZcuBEpPohFKKdgVdZuNTU8WstmvywPq55Njdw==}
|
||||
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
peerDependencies:
|
||||
size-limit: 12.0.0
|
||||
|
||||
'@size-limit/preset-small-lib@12.0.0':
|
||||
resolution: {integrity: sha512-HHHVQjZmj+8vg7qsHs1dd3Hmn8ygUsE5O2CfxnbCbHOGyUw7VodZGERh/+5ogVrF2DYza/DIo2PnCJZZETdTRA==}
|
||||
peerDependencies:
|
||||
size-limit: 12.0.0
|
||||
|
||||
'@so-ric/colorspace@1.1.6':
|
||||
resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==}
|
||||
|
||||
@@ -3274,6 +3297,10 @@ packages:
|
||||
buffer@6.0.3:
|
||||
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
|
||||
|
||||
bytes-iec@3.1.1:
|
||||
resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
cac@6.7.14:
|
||||
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -4706,6 +4733,10 @@ packages:
|
||||
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
|
||||
lilconfig@3.1.3:
|
||||
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
|
||||
@@ -5130,6 +5161,14 @@ packages:
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
nanoid@5.1.6:
|
||||
resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==}
|
||||
engines: {node: ^18 || >=20}
|
||||
hasBin: true
|
||||
|
||||
nanospinner@1.2.2:
|
||||
resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==}
|
||||
|
||||
nanostores@1.1.0:
|
||||
resolution: {integrity: sha512-yJBmDJr18xy47dbNVlHcgdPrulSn1nhSE6Ns9vTG+Nx9VPT6iV1MD6aQFp/t52zpf82FhLLTXAXr30NuCnxvwA==}
|
||||
engines: {node: ^20.0.0 || >=22.0.0}
|
||||
@@ -5879,6 +5918,16 @@ packages:
|
||||
engines: {node: '>=14.0.0', npm: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
size-limit@12.0.0:
|
||||
resolution: {integrity: sha512-JBG8dioIs0m2kHOhs9jD6E/tZKD08vmbf2bfqj/rJyNWqJxk/ZcakixjhYtsqdbi+AKVbfPkt3g2RRZiKaizYA==}
|
||||
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
jiti: ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
jiti:
|
||||
optional: true
|
||||
|
||||
slashes@3.0.12:
|
||||
resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==}
|
||||
|
||||
@@ -9075,6 +9124,22 @@ snapshots:
|
||||
|
||||
'@shikijs/vscode-textmate@10.0.2': {}
|
||||
|
||||
'@size-limit/esbuild@12.0.0(size-limit@12.0.0(jiti@2.6.1))':
|
||||
dependencies:
|
||||
esbuild: 0.27.2
|
||||
nanoid: 5.1.6
|
||||
size-limit: 12.0.0(jiti@2.6.1)
|
||||
|
||||
'@size-limit/file@12.0.0(size-limit@12.0.0(jiti@2.6.1))':
|
||||
dependencies:
|
||||
size-limit: 12.0.0(jiti@2.6.1)
|
||||
|
||||
'@size-limit/preset-small-lib@12.0.0(size-limit@12.0.0(jiti@2.6.1))':
|
||||
dependencies:
|
||||
'@size-limit/esbuild': 12.0.0(size-limit@12.0.0(jiti@2.6.1))
|
||||
'@size-limit/file': 12.0.0(size-limit@12.0.0(jiti@2.6.1))
|
||||
size-limit: 12.0.0(jiti@2.6.1)
|
||||
|
||||
'@so-ric/colorspace@1.1.6':
|
||||
dependencies:
|
||||
color: 5.0.3
|
||||
@@ -10095,6 +10160,8 @@ snapshots:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
|
||||
bytes-iec@3.1.1: {}
|
||||
|
||||
cac@6.7.14: {}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
@@ -11616,6 +11683,8 @@ snapshots:
|
||||
lightningcss-win32-arm64-msvc: 1.30.2
|
||||
lightningcss-win32-x64-msvc: 1.30.2
|
||||
|
||||
lilconfig@3.1.3: {}
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
|
||||
lint-staged@16.2.7:
|
||||
@@ -12297,6 +12366,12 @@ snapshots:
|
||||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
nanoid@5.1.6: {}
|
||||
|
||||
nanospinner@1.2.2:
|
||||
dependencies:
|
||||
picocolors: 1.1.1
|
||||
|
||||
nanostores@1.1.0: {}
|
||||
|
||||
neotraverse@0.6.18: {}
|
||||
@@ -13163,6 +13238,16 @@ snapshots:
|
||||
arg: 5.0.2
|
||||
sax: 1.4.3
|
||||
|
||||
size-limit@12.0.0(jiti@2.6.1):
|
||||
dependencies:
|
||||
bytes-iec: 3.1.1
|
||||
lilconfig: 3.1.3
|
||||
nanospinner: 1.2.2
|
||||
picocolors: 1.1.1
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
jiti: 2.6.1
|
||||
|
||||
slashes@3.0.12: {}
|
||||
|
||||
slice-ansi@7.1.2:
|
||||
|
||||
Reference in New Issue
Block a user