Skip to content

Commit ea65e26

Browse files
chore: integrate new bundle size tool (#18256)
* chore: integrate new bundle size tool * move getChangedEntriesInReport() to a separate file, reuse it in both reporters * Update packages/bundle-size/src/commands/compareReports.js Co-authored-by: ling1726 <lingfan.gao@microsoft.com> * Update packages/bundle-size/src/reporters/markdownReporter.js Co-authored-by: ling1726 <lingfan.gao@microsoft.com> * fix snapshot * do not mock chalk * add comment * update test * use Object.freeze, add tests for getChangedEntriesInReport * update cliReporter to exit early * refactor, do not use tuple, extract const * use snapshot serializer and strip-ansi * rename variables to clarify usage * refactor getRemoteReport * move sampleReport to __fixture__ * add comment to fix lint error * refactor getDirectionSymbol * refactor calculateDiffByMetric * use toEqual instead of snapshots * handle zero values * move url to const * add tests for compareReports & getRemoteReport * exclude tests from commands * fix regex Co-authored-by: ling1726 <lingfan.gao@microsoft.com>
1 parent 96ee2ca commit ea65e26

29 files changed

+932
-14
lines changed

azure-pipelines.bundlesize.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ jobs:
2828
yarn lage bundle-size --no-cache --verbose $(sinceArg)
2929
displayName: build packages & create reports
3030
31+
- script: |
32+
yarn bundle-size compare-reports --branch=$(System.PullRequest.TargetBranch) --output=markdown --verbose
33+
displayName: compare bundle size with base (PR only)
34+
condition: variables.isPR
35+
36+
- task: GithubPRComment@0
37+
displayName: Post results to PR (PR only)
38+
condition: eq(variables.isPR, true)
39+
inputs:
40+
githubOwner: microsoft
41+
githubRepo: 'fluentui'
42+
blobFilePath: 'packages/bundle-size/dist/bundle-size.md'
43+
status: 'success'
44+
uniqueId: 'bundleSizeComment9423'
45+
3146
- script: |
3247
yarn bundle-size upload-report --branch=$(Build.SourceBranchName) --commit-sha $(Build.SourceVersion)
3348
displayName: upload a report (base only)

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
"@types/jest-axe": "3.2.2",
106106
"@types/jju": "1.4.1",
107107
"@types/node": "10.17.55",
108+
"@types/node-fetch": "2.5.7",
108109
"@types/prettier": "2.2.3",
109110
"@types/react": "16.9.42",
110111
"@types/react-dom": "16.9.10",
@@ -164,6 +165,7 @@
164165
"lage": "0.27.0",
165166
"lerna": "^3.21.0",
166167
"lint-staged": "^10.2.9",
168+
"node-fetch": "2.6.1",
167169
"postcss": "8.2.10",
168170
"postcss-loader": "4.1.0",
169171
"postcss-modules": "4.1.3",
@@ -175,6 +177,7 @@
175177
"satisfied": "^1.1.1",
176178
"semver": "^6.2.0",
177179
"storybook-addon-performance": "0.14.0",
180+
"strip-ansi": "6.0.0",
178181
"style-loader": "2.0.0",
179182
"syncpack": "5.6.10",
180183
"tsconfig-paths": "3.9.0",

packages/bundle-size/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ export default {
2626

2727
### Commands
2828

29+
#### `compare-reports`
30+
31+
Compares local (requires call of `bundle-size measure` first) and remote results, provides output to CLI or to a Markdown file.
32+
33+
```sh
34+
yarn bundle-size compare-reports --branch=main --output=["cli"|"markdown"] [--quiet]
35+
```
36+
2937
#### `measure`
3038

3139
```sh
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const { emptyDiff } = require('../src/utils/compareResultsInReports');
2+
3+
/** @type {import('../src/utils/compareResultsInReports').ComparedReport} */
4+
const sampleComparedReport = [
5+
{
6+
packageName: 'foo-package',
7+
name: 'New entry',
8+
path: 'foo.fixture.js',
9+
minifiedSize: 1000,
10+
gzippedSize: 100,
11+
diff: emptyDiff,
12+
},
13+
{
14+
packageName: 'bar-package',
15+
name: 'An entry without diff',
16+
path: 'bar.fixture.js',
17+
minifiedSize: 1000,
18+
gzippedSize: 100,
19+
diff: {
20+
empty: false,
21+
22+
minified: { delta: 0, percent: '0%' },
23+
gzip: { delta: 0, percent: '0%' },
24+
},
25+
},
26+
{
27+
packageName: 'baz-package',
28+
name: 'An entry with diff',
29+
path: 'baz.fixture.js',
30+
minifiedSize: 1000,
31+
gzippedSize: 100,
32+
diff: {
33+
empty: false,
34+
35+
minified: { delta: 1000, percent: '100%' },
36+
gzip: { delta: 100, percent: '100%' },
37+
},
38+
},
39+
];
40+
41+
module.exports = sampleComparedReport;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/** @type {import('../src/utils/collectLocalReport').BundleSizeReport} */
2+
const sampleReport = [
3+
{
4+
packageName: 'foo-package',
5+
name: 'New entry',
6+
path: 'foo.fixture.js',
7+
minifiedSize: 1000,
8+
gzippedSize: 100,
9+
},
10+
{
11+
packageName: 'bar-package',
12+
name: 'An entry without diff',
13+
path: 'bar.fixture.js',
14+
minifiedSize: 1000,
15+
gzippedSize: 100,
16+
},
17+
{
18+
packageName: 'baz-package',
19+
name: 'An entry with diff',
20+
path: 'baz.fixture.js',
21+
minifiedSize: 1000,
22+
gzippedSize: 100,
23+
},
24+
];
25+
26+
module.exports = sampleReport;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
const chalk = require('chalk');
2+
3+
const cliReporter = require('../reporters/cliReporter');
4+
const markdownReporter = require('../reporters/markdownReporter');
5+
const collectLocalReport = require('../utils/collectLocalReport');
6+
const { compareResultsInReports } = require('../utils/compareResultsInReports');
7+
const getRemoteReport = require('../utils/getRemoteReport');
8+
const { hrToSeconds } = require('../utils/helpers');
9+
10+
/**
11+
* @param {typeof import('../index') & { branch: string, output: 'cli' | 'markdown' }} options
12+
*/
13+
async function compareReports(options) {
14+
const { branch, output, quiet } = options;
15+
const startTime = process.hrtime();
16+
17+
const localReportStartTime = process.hrtime();
18+
const localReport = await collectLocalReport();
19+
20+
if (!quiet) {
21+
console.log(
22+
[chalk.blue('[i]'), `Local report prepared in ${hrToSeconds(process.hrtime(localReportStartTime))}`].join(' '),
23+
);
24+
}
25+
26+
const remoteReportStartTime = process.hrtime();
27+
const { commitSHA, remoteReport } = await getRemoteReport(branch);
28+
29+
if (!quiet) {
30+
if (commitSHA === '') {
31+
console.log([chalk.blue('[i]'), `Remote report for "${branch}" branch was not found`].join(' '));
32+
} else {
33+
console.log(
34+
[
35+
chalk.blue('[i]'),
36+
`Remote report for "${commitSHA}" commit fetched in ${hrToSeconds(process.hrtime(remoteReportStartTime))}`,
37+
].join(' '),
38+
);
39+
}
40+
}
41+
42+
const result = compareResultsInReports(localReport, remoteReport);
43+
44+
switch (output) {
45+
case 'cli':
46+
await cliReporter(result);
47+
break;
48+
case 'markdown':
49+
await markdownReporter(result, commitSHA, quiet);
50+
break;
51+
}
52+
53+
if (!quiet) {
54+
console.log(`Completed in ${hrToSeconds(process.hrtime(startTime))}`);
55+
}
56+
}
57+
58+
// ---
59+
60+
/** @type {import('yargs').CommandModule} */
61+
const api = {
62+
command: 'compare-reports',
63+
describe: 'compares local and remote results',
64+
builder: {
65+
branch: {
66+
alias: 'b',
67+
type: 'string',
68+
description: 'A branch to compare against',
69+
default: 'main',
70+
},
71+
output: {
72+
alias: 'o',
73+
type: 'string',
74+
choices: ['cli', 'markdown'],
75+
description: 'Defines a reporter to produce output',
76+
default: 'cli',
77+
},
78+
},
79+
handler: compareReports,
80+
};
81+
82+
module.exports = api;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const getRemoteReport = jest.fn();
2+
const collectLocalReport = jest.fn();
3+
const compareResultsInReports = jest.fn();
4+
const cliReporter = jest.fn();
5+
6+
jest.mock('../reporters/cliReporter', () => cliReporter);
7+
jest.mock('../utils/collectLocalReport', () => collectLocalReport);
8+
jest.mock('../utils/compareResultsInReports', () => ({ compareResultsInReports }));
9+
jest.mock('../utils/getRemoteReport', () => getRemoteReport);
10+
11+
const sampleReport = require('../../__fixture__/sampleReport');
12+
const sampleComparedReport = require('../../__fixture__/sampleComparedReport');
13+
const { handler } = require('./compareReports');
14+
15+
describe('compareReports', () => {
16+
it('fetches remote report and compares it with a local data', async () => {
17+
const branchName = 'master';
18+
19+
getRemoteReport.mockImplementation(() => ({ commitSHA: 'test', remoteReport: sampleReport }));
20+
collectLocalReport.mockImplementation(() => sampleReport);
21+
compareResultsInReports.mockImplementation(() => sampleComparedReport);
22+
23+
await handler({ quiet: true, branch: branchName, output: 'cli' });
24+
25+
expect(getRemoteReport).toHaveBeenCalledWith(branchName);
26+
expect(compareResultsInReports).toHaveBeenCalledWith(sampleReport, sampleReport);
27+
expect(cliReporter).toHaveBeenCalledWith(sampleComparedReport);
28+
});
29+
});

packages/bundle-size/src/commands/measure.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ const fs = require('fs').promises;
44
const del = require('del');
55
const glob = require('glob');
66
const path = require('path');
7-
const prettyBytes = require('pretty-bytes');
87

98
const buildFixture = require('../utils/buildFixture');
10-
const { hrToSeconds } = require('../utils/helpers');
9+
const { formatBytes, hrToSeconds } = require('../utils/helpers');
1110
const prepareFixture = require('../utils/prepareFixture');
1211

1312
/**
@@ -49,7 +48,7 @@ async function measure(options) {
4948
const sortedMeasurements = [...measurements].sort((a, b) => a.path.localeCompare(b.path));
5049

5150
sortedMeasurements.forEach(r => {
52-
table.push([r.name, prettyBytes(r.minifiedSize), prettyBytes(r.gzippedSize)]);
51+
table.push([r.name, formatBytes(r.minifiedSize), formatBytes(r.gzippedSize)]);
5352
});
5453

5554
console.log(table.toString());

packages/bundle-size/src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
const yargs = require('yargs');
22

33
const cliSetup = yargs
4-
.commandDir('commands')
4+
.commandDir('commands', { exclude: /.test\.js$/ })
55
.option('quiet', {
66
alias: 'q',
77
type: 'boolean',
88
description: 'Suppress verbose build output',
99
default: false,
1010
})
11+
.scriptName('bundle-size')
1112
.version(false).argv;
1213

1314
module.exports = cliSetup;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`markdownReporter renders a report to a file 1`] = `
4+
"## 📊 Bundle size report
5+
6+
| Package & Exports | Baseline (minified/GZIP) | PR | Change |
7+
| :------------------------------------------------------------------------------------- | -----------------------: | ------------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
8+
| <samp>baz-package</samp> <br /> <abbr title='baz.fixture.js'>An entry with diff</abbr> | \`2 kB\`<br />\`200 B\` | \`1 kB\`<br />\`100 B\` | \`1 kB\` <img aria-hidden=\\"true\\" src=\\"https://microsoft.github.io/sizeAuditor-website/images/icons/IncreaseYellow.svg\\" /><br />\`100 B\` <img aria-hidden=\\"true\\" src=\\"https://microsoft.github.io/sizeAuditor-website/images/icons/IncreaseYellow.svg\\" /> |
9+
| <samp>foo-package</samp> <br /> <abbr title='foo.fixture.js'>New entry</abbr> | \`0 B\`<br />\`0 B\` | \`1 kB\`<br />\`100 B\` | 🆕 New entry |
10+
11+
<details>
12+
<summary>Unchanged fixtures</summary>
13+
14+
| Package & Exports | Size (minified/GZIP) |
15+
| ----------------------------------------------------------------------------------------- | -------------------: |
16+
| <samp>bar-package</samp> <br /> <abbr title='bar.fixture.js'>An entry without diff</abbr> | \`1 kB\`<br />\`100 B\` |
17+
18+
</details>
19+
<sub>🤖 This report was generated against <a href='https://github.com/microsoft/fluentui/commit/commit-hash'>commit-hash</a></sub>
20+
"
21+
`;

0 commit comments

Comments
 (0)