Skip to content

Commit 434fa08

Browse files
authored
Web Components: Add bundlesize plugin for build output check (uswds#180)
* remove single file and banner-specific vite config * add bundlesize config to vite * add failing condition to test CI pipeline * add passing condition * turn off bundlesize for storybook build * update lockfile * fix duplicate key from merge * use callback for entry map * move build helpers to external file and test * add test coverage for vite build helpers * refactor build helper for clarity
1 parent a451255 commit 434fa08

File tree

8 files changed

+182
-7
lines changed

8 files changed

+182
-7
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ storybook-static
3838
# Docker
3939
/.npm/_update-notifier-last-checked
4040
/.bash_history
41+
42+
# bundlesize plugin
43+
bundlemeta.json

.storybook/main.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,17 @@ const config = {
1414
name: "@storybook/web-components-vite",
1515
options: {},
1616
},
17+
viteFinal: async (config) => {
18+
/**
19+
* Unload the `vite-plugin-bundlesize` plugin.
20+
* This plugin is only used in the CI pipeline for output size of the
21+
* individual components.
22+
*/
23+
config.plugins = config.plugins.filter(
24+
(plugin) => plugin.name !== "vite-plugin-bundlesize",
25+
);
26+
27+
return config;
28+
},
1729
};
1830
export default config;

package-lock.json

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

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"stylelint-order": "^7.0.0",
8787
"typescript": "^5.8.3",
8888
"vite": "^7.1.5",
89+
"vite-plugin-bundlesize": "^0.3.0",
8990
"vite-plugin-lit-css": "^2.2.1",
9091
"vitest": "^3.2.4",
9192
"wait-on": "^7.2.0"

utils/build-helpers.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { describe, it, expect } from "vitest";
2+
import {
3+
mapEntryToLimit,
4+
type Entry,
5+
mapEntryToTuple,
6+
mapEntriesToKeyValue,
7+
} from "./build-helpers";
8+
9+
describe("mapEntryToLimit", () => {
10+
it("should correctly transform an entry to a Limit object", () => {
11+
const entry: Entry = {
12+
name: "components/index",
13+
path: "src/components/index",
14+
sizeLimit: "0.2 kB",
15+
};
16+
17+
const expected = {
18+
name: "components/index.js",
19+
limit: entry.sizeLimit,
20+
mode: "brotli",
21+
};
22+
23+
expect(mapEntryToLimit(entry)).toEqual(expected);
24+
});
25+
});
26+
27+
describe("mapEntriesToKeyValue", () => {
28+
it("should correctly transform an entry to a Limit object", () => {
29+
const entries: Array<Entry> = [
30+
{
31+
name: "components/index",
32+
path: "src/components/index",
33+
sizeLimit: "0.2 kB",
34+
},
35+
{
36+
name: "components/usa-banner",
37+
path: "src/components/usa-banner/index.ts",
38+
sizeLimit: "10 kB",
39+
},
40+
{
41+
name: "components/usa-link",
42+
path: "src/components/usa-link/index.js",
43+
sizeLimit: "0.8 kB",
44+
},
45+
];
46+
47+
const expected = {
48+
"components/index": "src/components/index",
49+
"components/usa-banner": "src/components/usa-banner/index.ts",
50+
"components/usa-link": "src/components/usa-link/index.js",
51+
};
52+
53+
expect(mapEntriesToKeyValue(entries)).toEqual(expected);
54+
});
55+
});

utils/build-helpers.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { type Limit } from "vite-plugin-bundlesize";
2+
3+
export type Entry = { name: string; path: string; sizeLimit: string };
4+
5+
/**
6+
* Converts an `Entry` object into a `Limit` object, mapping and transforming
7+
* the properties to adhere to the `Limit` type structure.
8+
*
9+
* @param {Entry} entry - The input object containing information about the entry.
10+
* @returns {Limit} - A transformed object with details about the limit, including
11+
* the updated name, size limit, and compression mode.
12+
*/
13+
export const mapEntryToLimit = (entry: Entry): Limit => {
14+
return {
15+
name: `${entry.name}.js`,
16+
limit: entry.sizeLimit,
17+
mode: "brotli",
18+
};
19+
};
20+
21+
/**
22+
* Maps an array of Entry objects to a key-value pair object, where each entry's name
23+
* is used as the key and its path is used as the value.
24+
*
25+
* @param {Entry[]} entries - The array of Entry objects to be mapped into key-value pairs.
26+
* @return {Record<string, string>} An object representing the key-value pairs derived from the entries,
27+
* where the key is the entry's name and the value is the entry's path.
28+
*/
29+
export function mapEntriesToKeyValue(entries: Entry[]): Record<string, string> {
30+
return Object.fromEntries(entries.map((entry) => [entry.name, entry.path]));
31+
}

vite.config.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,41 @@ import { resolve } from "path";
33
import browserslist from "browserslist";
44
import { browserslistToTargets } from "lightningcss";
55
import litCss from "vite-plugin-lit-css";
6+
import bundlesize from "vite-plugin-bundlesize";
7+
import {
8+
type Entry,
9+
mapEntriesToKeyValue,
10+
mapEntryToLimit,
11+
} from "./utils/build-helpers";
12+
13+
const entries: Array<Entry> = [
14+
{
15+
name: "components/index",
16+
path: "src/components/index",
17+
sizeLimit: "0.2 kB",
18+
},
19+
{
20+
name: "components/usa-banner",
21+
path: "src/components/usa-banner/index.ts",
22+
sizeLimit: "10 kB",
23+
},
24+
{
25+
name: "components/usa-link",
26+
path: "src/components/usa-link/index.js",
27+
sizeLimit: "0.8 kB",
28+
},
29+
];
630

731
export default defineConfig({
8-
plugins: [litCss()],
32+
plugins: [
33+
litCss(),
34+
bundlesize({
35+
limits: [
36+
...entries.map(mapEntryToLimit),
37+
{ name: "**/*.cjs", limit: "Infinity" },
38+
],
39+
}),
40+
],
941
resolve: {
1042
alias: {
1143
"@uswds/uswds": resolve(__dirname, "node_modules/@uswds/uswds/dist"),
@@ -29,12 +61,9 @@ export default defineConfig({
2961
},
3062
},
3163
build: {
64+
sourcemap: "hidden",
3265
lib: {
33-
entry: {
34-
"components/usa-banner": "src/components/usa-banner/index.ts",
35-
"components/usa-link": "src/components/usa-link/index.js",
36-
"components/index": "src/components/index",
37-
},
66+
entry: mapEntriesToKeyValue(entries),
3867
},
3968
rollupOptions: {
4069
external: ["lit"],

vitest.config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { defineConfig } from "vitest/config";
33
export default defineConfig({
44
test: {
55
environment: "jsdom",
6-
include: ["src/**/*.spec.{js,ts}", "src/**/*.test.{js,ts}"],
6+
include: [
7+
"src/**/*.spec.{js,ts}",
8+
"src/**/*.test.{js,ts}",
9+
"utils/**/*.spec.{js,ts}",
10+
"utils/**/*.test.{js,ts}",
11+
],
712
},
813
});

0 commit comments

Comments
 (0)