Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ inputs:
description: 'Whether to use the lockfile vs latest floating dependencies'
required: false
default: true

node-version:
description: 'The node version to use'
required: false
default: 18
runs:
using: 'composite'
steps:
Expand All @@ -15,7 +20,7 @@ runs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18
node-version: '${{ inputs.node-version }}'
registry-url: 'https://registry.npmjs.org'
cache: pnpm
- uses: actions/cache@v4
Expand Down
29 changes: 11 additions & 18 deletions .github/workflows/size-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ jobs:
runs-on: 'ubuntu-latest'

steps:
# better `du`
- run: sudo snap install dust

- uses: dawidd6/action-download-artifact@v9
with:
run_id: ${{ inputs.RUN_ID || github.event.workflow_run.id }}
Expand Down Expand Up @@ -67,7 +64,7 @@ jobs:
echo $contents
echo "prNumber=$contents" >> $GITHUB_OUTPUT

- name: "[PR] Get sizes for development outputs"
- name: "[PR] Get sizes"
id: dev
run: |
cat ${{ steps.find-pr-txt.outputs.txtPath }}
Expand All @@ -77,7 +74,7 @@ jobs:
done <<< $(cat ${{ steps.find-pr-txt.outputs.txtPath }})
echo 'EOF' >> $GITHUB_OUTPUT

- name: "[Main] Get sizes for development outputs"
- name: "[Main] Get sizes"
id: main-dev
run: |
cd main/
Expand All @@ -89,13 +86,13 @@ jobs:
done <<< $(cat out.txt)
echo 'EOF' >> $GITHUB_OUTPUT

- name: "[Dev] calculate diff"
- name: "calculate diff"
run: |
# diff exits with status 1 if there is a diff
diff -u main/out.txt ${{ steps.find-pr-txt.outputs.txtPath }} > dev-diff.txt || echo "Differences exist"
cat dev-diff.txt

- name: "[Dev] store diff in GITHUB_OUTPUT"
- name: "store diff in GITHUB_OUTPUT"
id: dev-diff
run: |
echo 'diffText<<EOF' >> $GITHUB_OUTPUT
Expand All @@ -106,7 +103,7 @@ jobs:



- name: "[Debug] collected data from artifacts"
- name: "collected data from artifacts"
run: |
echo "PR number"
echo -e "${{ steps.find-pr-number.outputs.prNumber }}"
Expand All @@ -124,20 +121,16 @@ jobs:
#########################
# Intended Layout:
#
# | | This PR | Main |
# | Dev | x1 | y1 |
# | Prod | x2 | y2 |
#
# NOTE: we we don't have a prod build for this library
# because we currently expect non-compiler usage
# (so consumers should have terser or similar properly configured for DCE)
# | This PR | Main |
# | x1 | y1 |
# | x2 | y2 |
#
#########################
- uses: mshick/add-pr-comment@v2
with:
issue: ${{ steps.find-pr-number.outputs.prNumber }}
message: |
<details><summary>Development Assets</summary>
<details><summary>Estimated Asset Sizes</summary>

Diff

Expand All @@ -147,9 +140,9 @@ jobs:

Details

<table><thead><tr><th></th><th>This PR</th><th>main</th></tr></thead>
<table><thead><tr><th>This PR</th><th>main</th></tr></thead>
<tbody>
<tr><td>Dev</td><td>
<tr><td>

```
${{ steps.dev.outputs.sizes }}
Expand Down
15 changes: 4 additions & 11 deletions .github/workflows/size-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,15 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: sudo snap install dust
with:
node-version: 22
- run: pnpm build

- name: "Get sizes for development outputs"
- name: "Get estimated sizes for production outputs"
id: main-dev
run: |
mkdir -p main
cd dist/packages
dust --ignore_hidden \
--reverse --apparent-size \
--no-percent-bars \
--only-dir \
--depth 20 \
> out.txt
cp out.txt ../../main/

node ./bin/minify-assets.mjs > ./main/out.txt

- uses: actions/upload-artifact@v4
with:
Expand Down
15 changes: 4 additions & 11 deletions .github/workflows/size-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,18 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
with:
node-version: 22
- run: pnpm build
- run: sudo snap install dust

- name: Save PR number
run: |
mkdir -p ./pr
echo "${{ github.event.number }}" > ./pr/NR

- name: "Get sizes for development outputs"
- name: "Get estimated sizes for production outputs"
id: dev
run: |
cd dist/packages
dust --ignore_hidden \
--reverse --apparent-size \
--no-percent-bars \
--only-dir \
--depth 20 \
> out.txt
cp out.txt ../../pr/
run: node ./bin/minify-assets.mjs > ./pr/out.txt


- uses: actions/upload-artifact@v4
Expand Down
219 changes: 219 additions & 0 deletions bin/minify-assets.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
const packages = [
'@ember/-internals',
'@ember/application',
'@ember/array',
'@ember/canary-features',
'@ember/component',
'@ember/controller',
'@ember/debug',
'@ember/deprecated-features',
'@ember/destroyable',
'@ember/enumerable',
'@ember/helper',
'@ember/instrumentation',
'@ember/modifier',
'@ember/object',
'@ember/owner',
'@ember/renderer',
'@ember/routing',
'@ember/runloop',
'@ember/service',
'@ember/template',
'@ember/template-compilation',
'@ember/template-compiler',
'@ember/template-factory',
'@ember/test',
'@ember/utils',
'@ember/version',
'@glimmer/destroyable',
'@glimmer/encoder',
'@glimmer/env',
'@glimmer/global-context',
'@glimmer/manager',
'@glimmer/node',
'@glimmer/opcode-compiler',
'@glimmer/owner',
'@glimmer/program',
'@glimmer/reference',
'@glimmer/runtime',
'@glimmer/tracking',
'@glimmer/util',
'@glimmer/validator',
'@glimmer/vm',
'@glimmer/wire-format',
];
import glob from 'glob';
import nodeGzip from 'node-gzip';

import { join } from 'node:path';
import { readFileSync, writeFileSync } from 'node:fs';
import { minify } from 'terser';
import { transformSync } from '@babel/core';
import * as brotli from 'brotli';
import { partial } from 'filesize';
const size = partial({ standard: 'jedec' });

const root = join(process.cwd(), 'dist/packages');

let min = {};
let br = {};
let gzip = {};

let packageData = {
ember: [
/* pkg, min, gz, br */
],
glimmer: [],
};

function totalMin(dataset) {
return dataset.reduce((a, b) => a + b[1], 0);
}

function totalGz(dataset) {
return dataset.reduce((a, b) => a + b[2], 0);
}

function totalBr(dataset) {
return dataset.reduce((a, b) => a + b[3], 0);
}

import { buildMacros } from '@embroider/macros/babel';

process.env.NODE_ENV = 'production';
process.env.EMBER_ENV = 'production';

const macros = buildMacros();
let babelOptions = {
cwd: process.cwd(),
plugins: [...macros.babelMacros],
};

for (const pkg of packages) {
let jsFiles = glob.sync(`${root}/${pkg}/**/*.js`);

for (let file of jsFiles) {
let source = readFileSync(file, 'utf8');
let transformed = transformSync(source, {
...babelOptions,
filename: file,
}).code;
let result = await minify(transformed, {
module: true,
mangle: false,
ecma: 2021,
compress: {
ecma: 2021,
passes: 3,
defaults: true,
keep_fargs: false,
keep_fnames: false,
/**
* Required for {{debugger}} to work
*/
drop_debugger: false,
},
});

let minFileName = file + '.min';
writeFileSync(minFileName, result.code);

let compressed = brotli.compress(result.code, {
// mode: 1, // 0 = generic, 1 = text, 2 = font (WOFF2)
quality: 11, // 0 - 11
// lgwin: 22, // window size
});

// console.log(brotli.decompress(brotli.compress(result.code)).length, result.code.length);

let compressedFileName = minFileName + '.br';
writeFileSync(compressedFileName, compressed);

let gzipFileName = minFileName + '.gz';
let gzipCompressed = (await nodeGzip.gzip(result.code)).toString();
writeFileSync(gzipFileName, gzipCompressed);

let minSize = new Blob([result.code]).size;
let brSize = new Blob([compressed.toString()]).size;
let gzSize = new Blob([gzipCompressed]).size;

min[pkg] = min[pkg] || 0;
min[pkg] += minSize;

br[pkg] = br[pkg] || 0;
br[pkg] += brSize;

gzip[pkg] = gzip[pkg] || 0;
gzip[pkg] += gzSize;
}
}

import { table } from 'table';

function printTable(data) {
// eslint-disable-next-line no-console
console.info(
table(data, {
drawHorizontalLine: (lineIndex, rowCount) => {
return lineIndex === 0 || lineIndex === 1 || lineIndex === 2 || lineIndex === rowCount;
},
})
);
}

printTable([
['', 'Min', 'Gzip' /* 'Brotli' */],
[
'Total',
size(Object.values(min).reduce((a, b) => a + b, 0)),
size(Object.values(gzip).reduce((a, b) => a + b, 0)),
// size(Object.values(br).reduce((a, b) => a + b, 0)),
],
]);

for (const pkg of packages.filter((p) => p.startsWith('@ember'))) {
let minSize = min[pkg];
let brSize = br[pkg];
let gzSize = gzip[pkg];

packageData.ember.push([pkg, minSize, gzSize, brSize]);
}
for (const pkg of packages.filter((p) => p.startsWith('@glimmer'))) {
let minSize = min[pkg];
let brSize = br[pkg];
let gzSize = gzip[pkg];

packageData.glimmer.push([pkg, minSize, gzSize, brSize]);
}

printTable([
['@ember/*', 'Min', 'Gzip' /* 'Brotli' */],
[
'Total',
size(totalMin(packageData.ember)),
size(totalGz(packageData.ember)),
// size(totalBr(packageData.ember)),
],
...packageData.ember.map((x) => [
x[0].replace('@ember/', ''),
size(x[1]),
size(x[2]),
// size(x[3]),
]),
]);

printTable([
['@glimmer/*', 'Min', 'Gzip' /* 'Brotli' */],
[
'Total',
size(totalMin(packageData.glimmer)),
size(totalGz(packageData.glimmer)),
// size(totalBr(packageData.glimmer)),
],
...packageData.glimmer.map((x) => [
x[0].replace('@glimmer/', ''),
size(x[1]),
size(x[2]),
// size(x[3]),
]),
]);
Loading