Skip to content

Commit 9b48198

Browse files
authored
Merge pull request #20930 from emberjs/main
2 parents ab874bc + e75e104 commit 9b48198

File tree

7 files changed

+376
-70
lines changed

7 files changed

+376
-70
lines changed

.github/actions/setup/action.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ inputs:
55
description: 'Whether to use the lockfile vs latest floating dependencies'
66
required: false
77
default: true
8+
9+
node-version:
10+
description: 'The node version to use'
11+
required: false
12+
default: 18
813
runs:
914
using: 'composite'
1015
steps:
@@ -15,7 +20,7 @@ runs:
1520
- name: Install Node.js
1621
uses: actions/setup-node@v4
1722
with:
18-
node-version: 18
23+
node-version: '${{ inputs.node-version }}'
1924
registry-url: 'https://registry.npmjs.org'
2025
cache: pnpm
2126
- uses: actions/cache@v4

.github/workflows/size-comment.yml

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ jobs:
2727
runs-on: 'ubuntu-latest'
2828

2929
steps:
30-
# better `du`
31-
- run: sudo snap install dust
32-
3330
- uses: dawidd6/action-download-artifact@v9
3431
with:
3532
run_id: ${{ inputs.RUN_ID || github.event.workflow_run.id }}
@@ -67,7 +64,7 @@ jobs:
6764
echo $contents
6865
echo "prNumber=$contents" >> $GITHUB_OUTPUT
6966
70-
- name: "[PR] Get sizes for development outputs"
67+
- name: "[PR] Get sizes"
7168
id: dev
7269
run: |
7370
cat ${{ steps.find-pr-txt.outputs.txtPath }}
@@ -77,7 +74,7 @@ jobs:
7774
done <<< $(cat ${{ steps.find-pr-txt.outputs.txtPath }})
7875
echo 'EOF' >> $GITHUB_OUTPUT
7976
80-
- name: "[Main] Get sizes for development outputs"
77+
- name: "[Main] Get sizes"
8178
id: main-dev
8279
run: |
8380
cd main/
@@ -89,13 +86,13 @@ jobs:
8986
done <<< $(cat out.txt)
9087
echo 'EOF' >> $GITHUB_OUTPUT
9188
92-
- name: "[Dev] calculate diff"
89+
- name: "calculate diff"
9390
run: |
9491
# diff exits with status 1 if there is a diff
9592
diff -u main/out.txt ${{ steps.find-pr-txt.outputs.txtPath }} > dev-diff.txt || echo "Differences exist"
9693
cat dev-diff.txt
9794
98-
- name: "[Dev] store diff in GITHUB_OUTPUT"
95+
- name: "store diff in GITHUB_OUTPUT"
9996
id: dev-diff
10097
run: |
10198
echo 'diffText<<EOF' >> $GITHUB_OUTPUT
@@ -106,7 +103,7 @@ jobs:
106103
107104
108105
109-
- name: "[Debug] collected data from artifacts"
106+
- name: "collected data from artifacts"
110107
run: |
111108
echo "PR number"
112109
echo -e "${{ steps.find-pr-number.outputs.prNumber }}"
@@ -124,20 +121,16 @@ jobs:
124121
#########################
125122
# Intended Layout:
126123
#
127-
# | | This PR | Main |
128-
# | Dev | x1 | y1 |
129-
# | Prod | x2 | y2 |
130-
#
131-
# NOTE: we we don't have a prod build for this library
132-
# because we currently expect non-compiler usage
133-
# (so consumers should have terser or similar properly configured for DCE)
124+
# | This PR | Main |
125+
# | x1 | y1 |
126+
# | x2 | y2 |
134127
#
135128
#########################
136129
- uses: mshick/add-pr-comment@v2
137130
with:
138131
issue: ${{ steps.find-pr-number.outputs.prNumber }}
139132
message: |
140-
<details><summary>Development Assets</summary>
133+
<details><summary>Estimated Asset Sizes</summary>
141134
142135
Diff
143136
@@ -147,9 +140,9 @@ jobs:
147140
148141
Details
149142
150-
<table><thead><tr><th></th><th>This PR</th><th>main</th></tr></thead>
143+
<table><thead><tr><th>This PR</th><th>main</th></tr></thead>
151144
<tbody>
152-
<tr><td>Dev</td><td>
145+
<tr><td>
153146
154147
```
155148
${{ steps.dev.outputs.sizes }}

.github/workflows/size-main.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,15 @@ jobs:
1313
steps:
1414
- uses: actions/checkout@v4
1515
- uses: ./.github/actions/setup
16-
- run: sudo snap install dust
16+
with:
17+
node-version: 22
1718
- run: pnpm build
1819

19-
- name: "Get sizes for development outputs"
20+
- name: "Get estimated sizes for production outputs"
2021
id: main-dev
2122
run: |
2223
mkdir -p main
23-
cd dist/packages
24-
dust --ignore_hidden \
25-
--reverse --apparent-size \
26-
--no-percent-bars \
27-
--only-dir \
28-
--depth 20 \
29-
> out.txt
30-
cp out.txt ../../main/
31-
24+
node ./bin/minify-assets.mjs > ./main/out.txt
3225
3326
- uses: actions/upload-artifact@v4
3427
with:

.github/workflows/size-pr.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,18 @@ jobs:
1818
steps:
1919
- uses: actions/checkout@v4
2020
- uses: ./.github/actions/setup
21+
with:
22+
node-version: 22
2123
- run: pnpm build
22-
- run: sudo snap install dust
2324

2425
- name: Save PR number
2526
run: |
2627
mkdir -p ./pr
2728
echo "${{ github.event.number }}" > ./pr/NR
2829
29-
- name: "Get sizes for development outputs"
30+
- name: "Get estimated sizes for production outputs"
3031
id: dev
31-
run: |
32-
cd dist/packages
33-
dust --ignore_hidden \
34-
--reverse --apparent-size \
35-
--no-percent-bars \
36-
--only-dir \
37-
--depth 20 \
38-
> out.txt
39-
cp out.txt ../../pr/
32+
run: node ./bin/minify-assets.mjs > ./pr/out.txt
4033

4134

4235
- uses: actions/upload-artifact@v4

bin/minify-assets.mjs

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
const packages = [
2+
'@ember/-internals',
3+
'@ember/application',
4+
'@ember/array',
5+
'@ember/canary-features',
6+
'@ember/component',
7+
'@ember/controller',
8+
'@ember/debug',
9+
'@ember/deprecated-features',
10+
'@ember/destroyable',
11+
'@ember/enumerable',
12+
'@ember/helper',
13+
'@ember/instrumentation',
14+
'@ember/modifier',
15+
'@ember/object',
16+
'@ember/owner',
17+
'@ember/renderer',
18+
'@ember/routing',
19+
'@ember/runloop',
20+
'@ember/service',
21+
'@ember/template',
22+
'@ember/template-compilation',
23+
'@ember/template-compiler',
24+
'@ember/template-factory',
25+
'@ember/test',
26+
'@ember/utils',
27+
'@ember/version',
28+
'@glimmer/destroyable',
29+
'@glimmer/encoder',
30+
'@glimmer/env',
31+
'@glimmer/global-context',
32+
'@glimmer/manager',
33+
'@glimmer/node',
34+
'@glimmer/opcode-compiler',
35+
'@glimmer/owner',
36+
'@glimmer/program',
37+
'@glimmer/reference',
38+
'@glimmer/runtime',
39+
'@glimmer/tracking',
40+
'@glimmer/util',
41+
'@glimmer/validator',
42+
'@glimmer/vm',
43+
'@glimmer/wire-format',
44+
];
45+
import glob from 'glob';
46+
import nodeGzip from 'node-gzip';
47+
48+
import { join } from 'node:path';
49+
import { readFileSync, writeFileSync } from 'node:fs';
50+
import { minify } from 'terser';
51+
import { transformSync } from '@babel/core';
52+
import * as brotli from 'brotli';
53+
import { partial } from 'filesize';
54+
const size = partial({ standard: 'jedec' });
55+
56+
const root = join(process.cwd(), 'dist/packages');
57+
58+
let min = {};
59+
let br = {};
60+
let gzip = {};
61+
62+
let packageData = {
63+
ember: [
64+
/* pkg, min, gz, br */
65+
],
66+
glimmer: [],
67+
};
68+
69+
function totalMin(dataset) {
70+
return dataset.reduce((a, b) => a + b[1], 0);
71+
}
72+
73+
function totalGz(dataset) {
74+
return dataset.reduce((a, b) => a + b[2], 0);
75+
}
76+
77+
// function totalBr(dataset) {
78+
// return dataset.reduce((a, b) => a + b[3], 0);
79+
// }
80+
81+
import { buildMacros } from '@embroider/macros/babel';
82+
83+
process.env.NODE_ENV = 'production';
84+
process.env.EMBER_ENV = 'production';
85+
86+
const macros = buildMacros();
87+
let babelOptions = {
88+
cwd: process.cwd(),
89+
plugins: [...macros.babelMacros],
90+
};
91+
92+
for (const pkg of packages) {
93+
let jsFiles = glob.sync(`${root}/${pkg}/**/*.js`);
94+
95+
for (let file of jsFiles) {
96+
let source = readFileSync(file, 'utf8');
97+
let transformed = transformSync(source, {
98+
...babelOptions,
99+
filename: file,
100+
}).code;
101+
let result = await minify(transformed, {
102+
module: true,
103+
mangle: false,
104+
ecma: 2021,
105+
compress: {
106+
ecma: 2021,
107+
passes: 3,
108+
defaults: true,
109+
keep_fargs: false,
110+
keep_fnames: false,
111+
/**
112+
* Required for {{debugger}} to work
113+
*/
114+
drop_debugger: false,
115+
},
116+
});
117+
118+
let minFileName = file + '.min';
119+
writeFileSync(minFileName, result.code);
120+
121+
let compressed = brotli.compress(result.code, {
122+
// mode: 1, // 0 = generic, 1 = text, 2 = font (WOFF2)
123+
quality: 11, // 0 - 11
124+
// lgwin: 22, // window size
125+
});
126+
127+
// console.log(brotli.decompress(brotli.compress(result.code)).length, result.code.length);
128+
129+
let compressedFileName = minFileName + '.br';
130+
writeFileSync(compressedFileName, compressed);
131+
132+
let gzipFileName = minFileName + '.gz';
133+
let gzipCompressed = (await nodeGzip.gzip(result.code)).toString();
134+
writeFileSync(gzipFileName, gzipCompressed);
135+
136+
let minSize = new Blob([result.code]).size;
137+
let brSize = new Blob([compressed.toString()]).size;
138+
let gzSize = new Blob([gzipCompressed]).size;
139+
140+
min[pkg] = min[pkg] || 0;
141+
min[pkg] += minSize;
142+
143+
br[pkg] = br[pkg] || 0;
144+
br[pkg] += brSize;
145+
146+
gzip[pkg] = gzip[pkg] || 0;
147+
gzip[pkg] += gzSize;
148+
}
149+
}
150+
151+
import { table } from 'table';
152+
153+
function printTable(data) {
154+
// eslint-disable-next-line no-console
155+
console.info(
156+
table(data, {
157+
drawHorizontalLine: (lineIndex, rowCount) => {
158+
return lineIndex === 0 || lineIndex === 1 || lineIndex === 2 || lineIndex === rowCount;
159+
},
160+
})
161+
);
162+
}
163+
164+
printTable([
165+
['', 'Min', 'Gzip' /* 'Brotli' */],
166+
[
167+
'Total',
168+
size(Object.values(min).reduce((a, b) => a + b, 0)),
169+
size(Object.values(gzip).reduce((a, b) => a + b, 0)),
170+
// size(Object.values(br).reduce((a, b) => a + b, 0)),
171+
],
172+
]);
173+
174+
for (const pkg of packages.filter((p) => p.startsWith('@ember'))) {
175+
let minSize = min[pkg];
176+
let brSize = br[pkg];
177+
let gzSize = gzip[pkg];
178+
179+
packageData.ember.push([pkg, minSize, gzSize, brSize]);
180+
}
181+
for (const pkg of packages.filter((p) => p.startsWith('@glimmer'))) {
182+
let minSize = min[pkg];
183+
let brSize = br[pkg];
184+
let gzSize = gzip[pkg];
185+
186+
packageData.glimmer.push([pkg, minSize, gzSize, brSize]);
187+
}
188+
189+
printTable([
190+
['@ember/*', 'Min', 'Gzip' /* 'Brotli' */],
191+
[
192+
'Total',
193+
size(totalMin(packageData.ember)),
194+
size(totalGz(packageData.ember)),
195+
// size(totalBr(packageData.ember)),
196+
],
197+
...packageData.ember.map((x) => [
198+
x[0].replace('@ember/', ''),
199+
size(x[1]),
200+
size(x[2]),
201+
// size(x[3]),
202+
]),
203+
]);
204+
205+
printTable([
206+
['@glimmer/*', 'Min', 'Gzip' /* 'Brotli' */],
207+
[
208+
'Total',
209+
size(totalMin(packageData.glimmer)),
210+
size(totalGz(packageData.glimmer)),
211+
// size(totalBr(packageData.glimmer)),
212+
],
213+
...packageData.glimmer.map((x) => [
214+
x[0].replace('@glimmer/', ''),
215+
size(x[1]),
216+
size(x[2]),
217+
// size(x[3]),
218+
]),
219+
]);

0 commit comments

Comments
 (0)