@node-cli/bundlesize 4.4.0 → 4.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,6 +14,51 @@
14
14
 
15
15
  A configuration file must be provided via the `-c` parameter.
16
16
 
17
+ ### Type-Safe Configuration
18
+
19
+ For IDE autocompletion and validation, you can use either JSDoc type hints or the `defineConfig` helper function.
20
+
21
+ #### Using JSDoc (recommended for JavaScript configs)
22
+
23
+ ```js
24
+ // @ts-check
25
+ /** @type {import('@node-cli/bundlesize').BundlesizeConfig} */
26
+ export default {
27
+ sizes: [
28
+ {
29
+ path: "dist/bundle.js",
30
+ limit: "10 kB"
31
+ }
32
+ ]
33
+ };
34
+ ```
35
+
36
+ #### Using defineConfig helper
37
+
38
+ ```js
39
+ // @ts-check
40
+ import { defineConfig } from "@node-cli/bundlesize";
41
+
42
+ export default defineConfig({
43
+ sizes: [
44
+ {
45
+ path: "dist/bundle.js",
46
+ limit: "10 kB"
47
+ }
48
+ ]
49
+ });
50
+ ```
51
+
52
+ Both approaches provide:
53
+
54
+ - Autocompletion for configuration options
55
+ - Inline documentation for each property
56
+ - Type validation in your IDE
57
+
58
+ **Note**: The `// @ts-check` comment enables TypeScript checking for the file, which is required for validation errors to appear.
59
+
60
+ ### Configuration Options
61
+
17
62
  For the size option, it must export an object named "size" which is an array of objects with the following properties:
18
63
 
19
64
  - `path`: the path to the file to check
@@ -199,6 +244,8 @@ export default {
199
244
  };
200
245
  ```
201
246
 
247
+ **Note on threshold with subgroups**: When using subgroup headers, the threshold is applied consistently. If individual file changes are below the threshold (and thus treated as zero), the sub-bundle total will also reflect this. For example, if file A changes by +3 bytes and file B changes by +4 bytes with a threshold of 5, both individual changes are ignored, and the sub-bundle will show no change (even though the raw total would be +7 bytes).
248
+
202
249
  #### Report with subgroup headers (multiple tables)
203
250
 
204
251
  You can interleave header objects inside the `sizes` array to break the report output into multiple markdown tables. Each header object must contain a `header` property (any markdown heading is allowed). A sub-bundle total line will be printed after each group along with its diff to previous stats (if available), followed by the overall bundle size and status at the end.
@@ -0,0 +1,103 @@
1
+ import type { FooterProperties } from "./utilities.js";
2
+ /**
3
+ * Configuration for a single file size entry.
4
+ */
5
+ export interface SizeEntry {
6
+ /**
7
+ * Path to the file to check. Supports glob patterns.
8
+ * Special placeholders:
9
+ * - `<hash>`: matches content hashes (e.g., `bundle-<hash>.js`)
10
+ * - `<semver>`: matches semantic versions (e.g., `lib-<semver>.js`)
11
+ */
12
+ path: string;
13
+ /**
14
+ * Maximum allowed size for the file (gzipped).
15
+ * Format: number followed by unit (B, kB, KB, MB, GB, TB, PB)
16
+ * @example "10 kB", "1.5 MB", "500 B"
17
+ */
18
+ limit: string;
19
+ /**
20
+ * Optional alias for the file in reports.
21
+ * Useful for giving meaningful names to files with hash patterns.
22
+ */
23
+ alias?: string;
24
+ }
25
+ /**
26
+ * Configuration for a header entry (group separator in reports).
27
+ */
28
+ export interface HeaderEntry {
29
+ /**
30
+ * Header text to display as a group separator in reports.
31
+ */
32
+ header: string;
33
+ }
34
+ /**
35
+ * Column definition for the report table.
36
+ */
37
+ export interface ColumnDefinition {
38
+ [key: string]: string;
39
+ }
40
+ /**
41
+ * Configuration for generating comparison reports.
42
+ */
43
+ export interface ReportConfiguration {
44
+ /**
45
+ * Path to the current stats JSON file (relative to config file).
46
+ */
47
+ current: string;
48
+ /**
49
+ * Path to the previous stats JSON file for comparison (relative to config file).
50
+ */
51
+ previous: string;
52
+ /**
53
+ * Custom header text for the report.
54
+ * @default "## Bundle Size"
55
+ */
56
+ header?: string;
57
+ /**
58
+ * Custom footer function for the report.
59
+ * Receives an object with limitReached, overallDiff, and totalGzipSize.
60
+ */
61
+ footer?: (args: FooterProperties) => string;
62
+ /**
63
+ * Column definitions for the report table.
64
+ * @default [{ status: "Status" }, { file: "File" }, { size: "Size (Gzip)" }, { limits: "Limits" }]
65
+ */
66
+ columns?: ColumnDefinition[];
67
+ /**
68
+ * Minimum gzip size change in bytes to consider as a change.
69
+ * Changes below this threshold are treated as no change.
70
+ * @default 0
71
+ */
72
+ threshold?: number;
73
+ }
74
+ /**
75
+ * Bundlesize configuration object.
76
+ */
77
+ export interface BundlesizeConfig {
78
+ /**
79
+ * Array of file size entries to check.
80
+ * Each entry can be either a SizeEntry (file to check) or HeaderEntry (group separator).
81
+ */
82
+ sizes?: (SizeEntry | HeaderEntry)[];
83
+ /**
84
+ * Configuration for generating comparison reports.
85
+ */
86
+ report?: ReportConfiguration;
87
+ }
88
+ /**
89
+ * Helper function to define bundlesize configuration with full type support.
90
+ * Provides IntelliSense and type checking for configuration files.
91
+ *
92
+ * @example
93
+ * ```js
94
+ * import { defineConfig } from "@node-cli/bundlesize";
95
+ *
96
+ * export default defineConfig({
97
+ * sizes: [
98
+ * { path: "dist/bundle.js", limit: "10 kB" }
99
+ * ]
100
+ * });
101
+ * ```
102
+ */
103
+ export declare function defineConfig(config: BundlesizeConfig): BundlesizeConfig;
package/dist/config.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Helper function to define bundlesize configuration with full type support.
3
+ * Provides IntelliSense and type checking for configuration files.
4
+ *
5
+ * @example
6
+ * ```js
7
+ * import { defineConfig } from "@node-cli/bundlesize";
8
+ *
9
+ * export default defineConfig({
10
+ * sizes: [
11
+ * { path: "dist/bundle.js", limit: "10 kB" }
12
+ * ]
13
+ * });
14
+ * ```
15
+ */ export function defineConfig(config) {
16
+ return config;
17
+ }
18
+
19
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import type { FooterProperties } from \"./utilities.js\";\n\n/**\n * Configuration for a single file size entry.\n */\nexport interface SizeEntry {\n\t/**\n\t * Path to the file to check. Supports glob patterns.\n\t * Special placeholders:\n\t * - `<hash>`: matches content hashes (e.g., `bundle-<hash>.js`)\n\t * - `<semver>`: matches semantic versions (e.g., `lib-<semver>.js`)\n\t */\n\tpath: string;\n\t/**\n\t * Maximum allowed size for the file (gzipped).\n\t * Format: number followed by unit (B, kB, KB, MB, GB, TB, PB)\n\t * @example \"10 kB\", \"1.5 MB\", \"500 B\"\n\t */\n\tlimit: string;\n\t/**\n\t * Optional alias for the file in reports.\n\t * Useful for giving meaningful names to files with hash patterns.\n\t */\n\talias?: string;\n}\n\n/**\n * Configuration for a header entry (group separator in reports).\n */\nexport interface HeaderEntry {\n\t/**\n\t * Header text to display as a group separator in reports.\n\t */\n\theader: string;\n}\n\n/**\n * Column definition for the report table.\n */\nexport interface ColumnDefinition {\n\t[key: string]: string;\n}\n\n/**\n * Configuration for generating comparison reports.\n */\nexport interface ReportConfiguration {\n\t/**\n\t * Path to the current stats JSON file (relative to config file).\n\t */\n\tcurrent: string;\n\t/**\n\t * Path to the previous stats JSON file for comparison (relative to config file).\n\t */\n\tprevious: string;\n\t/**\n\t * Custom header text for the report.\n\t * @default \"## Bundle Size\"\n\t */\n\theader?: string;\n\t/**\n\t * Custom footer function for the report.\n\t * Receives an object with limitReached, overallDiff, and totalGzipSize.\n\t */\n\tfooter?: (args: FooterProperties) => string;\n\t/**\n\t * Column definitions for the report table.\n\t * @default [{ status: \"Status\" }, { file: \"File\" }, { size: \"Size (Gzip)\" }, { limits: \"Limits\" }]\n\t */\n\tcolumns?: ColumnDefinition[];\n\t/**\n\t * Minimum gzip size change in bytes to consider as a change.\n\t * Changes below this threshold are treated as no change.\n\t * @default 0\n\t */\n\tthreshold?: number;\n}\n\n/**\n * Bundlesize configuration object.\n */\nexport interface BundlesizeConfig {\n\t/**\n\t * Array of file size entries to check.\n\t * Each entry can be either a SizeEntry (file to check) or HeaderEntry (group separator).\n\t */\n\tsizes?: (SizeEntry | HeaderEntry)[];\n\t/**\n\t * Configuration for generating comparison reports.\n\t */\n\treport?: ReportConfiguration;\n}\n\n/**\n * Helper function to define bundlesize configuration with full type support.\n * Provides IntelliSense and type checking for configuration files.\n *\n * @example\n * ```js\n * import { defineConfig } from \"@node-cli/bundlesize\";\n *\n * export default defineConfig({\n * sizes: [\n * { path: \"dist/bundle.js\", limit: \"10 kB\" }\n * ]\n * });\n * ```\n */\nexport function defineConfig(config: BundlesizeConfig): BundlesizeConfig {\n\treturn config;\n}\n"],"names":["defineConfig","config"],"mappings":"AA6FA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASA,aAAaC,MAAwB;IACpD,OAAOA;AACR"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  export * from "./bundlesize";
6
+ export * from "./config";
6
7
  export * from "./defaults";
7
8
  export * from "./getRawStats";
8
9
  export * from "./parse";
@@ -105,17 +105,15 @@ export const reportStats = async ({ flags })=>{
105
105
  }
106
106
  }
107
107
  let subGroupAccumulatedSize = 0;
108
+ let subGroupAccumulatedDiff = 0;
108
109
  let subGroupAccumulatedPrevSize = 0;
109
110
  let hasSubGroup = false;
110
111
  const flushSubGroup = ()=>{
111
112
  if (!hasSubGroup) {
112
113
  return;
113
114
  }
114
- let diff = subGroupAccumulatedSize - subGroupAccumulatedPrevSize;
115
- // Apply threshold: if the absolute diff is below threshold, treat as no change
116
- if (Math.abs(diff) < threshold) {
117
- diff = 0;
118
- }
115
+ // Use the accumulated thresholded diff directly
116
+ const diff = subGroupAccumulatedDiff;
119
117
  let diffString = "";
120
118
  if (diff !== 0 && subGroupAccumulatedPrevSize !== 0) {
121
119
  const sign = diff > 0 ? "+" : "-";
@@ -129,6 +127,7 @@ export const reportStats = async ({ flags })=>{
129
127
  })}${diffString}`, "");
130
128
  }
131
129
  subGroupAccumulatedSize = 0;
130
+ subGroupAccumulatedDiff = 0;
132
131
  subGroupAccumulatedPrevSize = 0;
133
132
  hasSubGroup = false;
134
133
  };
@@ -153,6 +152,7 @@ export const reportStats = async ({ flags })=>{
153
152
  }
154
153
  let diffString = "";
155
154
  let previousFileSizeGzip = 0;
155
+ let thresholdedDiff = 0;
156
156
  if (previousStats && previousVersion) {
157
157
  const previousFileStats = previousStats.data[previousVersion] && previousStats.data[previousVersion][key];
158
158
  previousFileSizeGzip = previousFileStats?.fileSizeGzip || 0;
@@ -161,6 +161,7 @@ export const reportStats = async ({ flags })=>{
161
161
  if (Math.abs(diff) < threshold) {
162
162
  diff = 0;
163
163
  }
164
+ thresholdedDiff = diff;
164
165
  overallDiff += diff;
165
166
  diffString = diff === 0 || diff === item.fileSizeGzip ? "" : ` (${diff > 0 ? "+" : "-"}${bytes(Math.abs(diff), {
166
167
  unitSeparator: " "
@@ -168,6 +169,7 @@ export const reportStats = async ({ flags })=>{
168
169
  }
169
170
  totalGzipSize += item.fileSizeGzip;
170
171
  subGroupAccumulatedSize += item.fileSizeGzip;
172
+ subGroupAccumulatedDiff += thresholdedDiff;
171
173
  subGroupAccumulatedPrevSize += previousFileSizeGzip;
172
174
  hasSubGroup = true;
173
175
  rowsMD.push(addMDrow({
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/reportStats.ts"],"sourcesContent":["import { basename, dirname, join } from \"node:path\";\nimport bytes from \"bytes\";\nimport { DEFAULT_THRESHOLD } from \"./defaults.js\";\nimport type { FooterProperties } from \"./utilities.js\";\nimport {\n\taddMDrow,\n\tformatFooter,\n\tgetMostRecentVersion,\n\tgetOutputFile,\n\tpercentFormatter,\n\treadJSONFile,\n\tvalidateConfigurationFile,\n} from \"./utilities.js\";\n\ntype ReportConfiguration = {\n\tcurrent: string;\n\tprevious: string;\n\theader?: string;\n\tfooter?: (arguments_: FooterProperties) => string;\n\tcolumns?: { [key: string]: string }[];\n\tthreshold?: number;\n};\n\ninterface HeaderSizeEntry {\n\theader: string;\n}\ninterface FileSizeEntry {\n\tpath: string;\n\tlimit: string;\n\talias?: string;\n}\ntype SizesConfiguration = Array<HeaderSizeEntry | FileSizeEntry>;\n\nconst isHeaderEntry = (\n\tentry: HeaderSizeEntry | FileSizeEntry,\n): entry is HeaderSizeEntry => \"header\" in entry;\n\ntype ReportCompare = {\n\tdata: string;\n\texitCode: number;\n\texitMessage: string;\n\toutputFile: string;\n};\n\nexport const reportStats = async ({ flags }): Promise<ReportCompare> => {\n\tconst result: ReportCompare = {\n\t\texitCode: 0,\n\t\texitMessage: \"\",\n\t\toutputFile: \"\",\n\t\tdata: \"\",\n\t};\n\n\tlet previousStats, previousVersion: string;\n\tconst isValidConfigResult = validateConfigurationFile(flags.configuration);\n\tif (isValidConfigResult.exitMessage !== \"\") {\n\t\treturn { ...result, ...isValidConfigResult };\n\t}\n\n\tconst configurationFile = isValidConfigResult.data;\n\tconst outputFile = getOutputFile(flags.output);\n\tresult.outputFile = outputFile;\n\n\tconst configuration: {\n\t\treport: ReportConfiguration;\n\t\tsizes?: SizesConfiguration;\n\t} = await import(configurationFile).then((m) => m.default);\n\n\tconst currentStats = readJSONFile(\n\t\tjoin(dirname(configurationFile), configuration.report.current),\n\t);\n\tif (currentStats.exitMessage !== \"\") {\n\t\treturn { ...result, ...currentStats };\n\t}\n\n\ttry {\n\t\tpreviousStats = readJSONFile(\n\t\t\tjoin(dirname(configurationFile), configuration.report.previous),\n\t\t);\n\t\tif (previousStats.exitMessage !== \"\") {\n\t\t\treturn { ...result, ...previousStats };\n\t\t}\n\t\tpreviousVersion = getMostRecentVersion(previousStats.data);\n\t} catch {\n\t\t// no previous stats available.\n\t}\n\n\tconst currentVersion = getMostRecentVersion(currentStats.data);\n\n\tlet limitReached = false;\n\tlet overallDiff = 0;\n\tlet totalGzipSize = 0;\n\n\tconst threshold = configuration.report.threshold ?? DEFAULT_THRESHOLD;\n\tconst headerString = configuration.report.header || \"## Bundle Size\";\n\tconst footerFormatter = configuration.report.footer || formatFooter;\n\tconst columns = configuration.report.columns || [\n\t\t{ status: \"Status\" },\n\t\t{ file: \"File\" },\n\t\t{ size: \"Size (Gzip)\" },\n\t\t{ limits: \"Limits\" },\n\t];\n\n\tconst rowsMD: string[] = [];\n\tconst hasGroupHeaders = Boolean(configuration.sizes?.some(isHeaderEntry));\n\tif (!hasGroupHeaders) {\n\t\trowsMD.push(addMDrow({ type: \"header\", columns }));\n\t}\n\n\t// Build ordered keys based on configuration.sizes if present.\n\tconst orderedKeys: Array<{\n\t\ttype: \"header\" | \"item\";\n\t\tvalue: string;\n\t\theader?: string;\n\t}> = [];\n\tif (configuration.sizes && Array.isArray(configuration.sizes)) {\n\t\tfor (const entry of configuration.sizes) {\n\t\t\tif (isHeaderEntry(entry)) {\n\t\t\t\torderedKeys.push({ type: \"header\", value: \"\", header: entry.header });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// entry is FileSizeEntry here.\n\t\t\tif (entry.alias && currentStats.data[currentVersion][entry.alias]) {\n\t\t\t\torderedKeys.push({ type: \"item\", value: entry.alias });\n\t\t\t} else if (currentStats.data[currentVersion][entry.path]) {\n\t\t\t\torderedKeys.push({ type: \"item\", value: entry.path });\n\t\t\t}\n\t\t}\n\t}\n\n\tif (orderedKeys.length === 0) {\n\t\tfor (const key of Object.keys(currentStats.data[currentVersion])) {\n\t\t\torderedKeys.push({ type: \"item\", value: key });\n\t\t}\n\t}\n\n\tlet subGroupAccumulatedSize = 0;\n\tlet subGroupAccumulatedPrevSize = 0;\n\tlet hasSubGroup = false;\n\tconst flushSubGroup = () => {\n\t\tif (!hasSubGroup) {\n\t\t\treturn;\n\t\t}\n\t\tlet diff = subGroupAccumulatedSize - subGroupAccumulatedPrevSize;\n\t\t// Apply threshold: if the absolute diff is below threshold, treat as no change\n\t\tif (Math.abs(diff) < threshold) {\n\t\t\tdiff = 0;\n\t\t}\n\t\tlet diffString = \"\";\n\t\tif (diff !== 0 && subGroupAccumulatedPrevSize !== 0) {\n\t\t\tconst sign = diff > 0 ? \"+\" : \"-\";\n\t\t\tdiffString = ` (${sign}${bytes(Math.abs(diff), { unitSeparator: \" \" })} ${percentFormatter(\n\t\t\t\tdiff / subGroupAccumulatedPrevSize,\n\t\t\t)})`;\n\t\t}\n\t\tif (hasGroupHeaders) {\n\t\t\trowsMD.push(\n\t\t\t\t`\\nSub-bundle size: ${bytes(subGroupAccumulatedSize, {\n\t\t\t\t\tunitSeparator: \" \",\n\t\t\t\t})}${diffString}`,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t}\n\t\tsubGroupAccumulatedSize = 0;\n\t\tsubGroupAccumulatedPrevSize = 0;\n\t\thasSubGroup = false;\n\t};\n\n\tfor (const entry of orderedKeys) {\n\t\tif (entry.type === \"header\") {\n\t\t\tflushSubGroup();\n\t\t\trowsMD.push(\"\", entry.header as string, \"\");\n\t\t\trowsMD.push(addMDrow({ type: \"header\", columns }));\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = entry.value;\n\t\tconst item = currentStats.data[currentVersion][key];\n\t\tif (!item) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = basename(key);\n\t\tif (!item.passed) {\n\t\t\tlimitReached = true;\n\t\t}\n\n\t\tlet diffString = \"\";\n\t\tlet previousFileSizeGzip = 0;\n\t\tif (previousStats && previousVersion) {\n\t\t\tconst previousFileStats =\n\t\t\t\tpreviousStats.data[previousVersion] &&\n\t\t\t\tpreviousStats.data[previousVersion][key];\n\t\t\tpreviousFileSizeGzip = previousFileStats?.fileSizeGzip || 0;\n\t\t\tlet diff = item.fileSizeGzip - previousFileSizeGzip;\n\t\t\t// Apply threshold: if the absolute diff is below threshold, treat as no change\n\t\t\tif (Math.abs(diff) < threshold) {\n\t\t\t\tdiff = 0;\n\t\t\t}\n\t\t\toverallDiff += diff;\n\t\t\tdiffString =\n\t\t\t\tdiff === 0 || diff === item.fileSizeGzip\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: ` (${diff > 0 ? \"+\" : \"-\"}${bytes(Math.abs(diff), { unitSeparator: \" \" })} ${percentFormatter(\n\t\t\t\t\t\t\tpreviousFileSizeGzip === 0 ? 0 : diff / previousFileSizeGzip,\n\t\t\t\t\t\t)})`;\n\t\t}\n\n\t\ttotalGzipSize += item.fileSizeGzip;\n\t\tsubGroupAccumulatedSize += item.fileSizeGzip;\n\t\tsubGroupAccumulatedPrevSize += previousFileSizeGzip;\n\t\thasSubGroup = true;\n\n\t\trowsMD.push(\n\t\t\taddMDrow({\n\t\t\t\ttype: \"row\",\n\t\t\t\tpassed: item.passed,\n\t\t\t\tname: name,\n\t\t\t\tsize: item.fileSizeGzip,\n\t\t\t\tdiff: diffString,\n\t\t\t\tlimit: item.limit,\n\t\t\t\tcolumns,\n\t\t\t}),\n\t\t);\n\t}\n\n\tflushSubGroup();\n\n\tconst template = `\n${headerString}\n${rowsMD.join(\"\\n\")}\n\n${footerFormatter({ limitReached, overallDiff, totalGzipSize })}\n`;\n\n\tif (limitReached) {\n\t\tresult.exitCode = 1;\n\t}\n\tresult.data = template;\n\treturn result;\n};\n"],"names":["basename","dirname","join","bytes","DEFAULT_THRESHOLD","addMDrow","formatFooter","getMostRecentVersion","getOutputFile","percentFormatter","readJSONFile","validateConfigurationFile","isHeaderEntry","entry","reportStats","flags","result","exitCode","exitMessage","outputFile","data","previousStats","previousVersion","isValidConfigResult","configuration","configurationFile","output","then","m","default","currentStats","report","current","previous","currentVersion","limitReached","overallDiff","totalGzipSize","threshold","headerString","header","footerFormatter","footer","columns","status","file","size","limits","rowsMD","hasGroupHeaders","Boolean","sizes","some","push","type","orderedKeys","Array","isArray","value","alias","path","length","key","Object","keys","subGroupAccumulatedSize","subGroupAccumulatedPrevSize","hasSubGroup","flushSubGroup","diff","Math","abs","diffString","sign","unitSeparator","item","name","passed","previousFileSizeGzip","previousFileStats","fileSizeGzip","limit","template"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/reportStats.ts"],"sourcesContent":["import { basename, dirname, join } from \"node:path\";\nimport bytes from \"bytes\";\nimport { DEFAULT_THRESHOLD } from \"./defaults.js\";\nimport type { FooterProperties } from \"./utilities.js\";\nimport {\n\taddMDrow,\n\tformatFooter,\n\tgetMostRecentVersion,\n\tgetOutputFile,\n\tpercentFormatter,\n\treadJSONFile,\n\tvalidateConfigurationFile,\n} from \"./utilities.js\";\n\ntype ReportConfiguration = {\n\tcurrent: string;\n\tprevious: string;\n\theader?: string;\n\tfooter?: (arguments_: FooterProperties) => string;\n\tcolumns?: { [key: string]: string }[];\n\tthreshold?: number;\n};\n\ninterface HeaderSizeEntry {\n\theader: string;\n}\ninterface FileSizeEntry {\n\tpath: string;\n\tlimit: string;\n\talias?: string;\n}\ntype SizesConfiguration = Array<HeaderSizeEntry | FileSizeEntry>;\n\nconst isHeaderEntry = (\n\tentry: HeaderSizeEntry | FileSizeEntry,\n): entry is HeaderSizeEntry => \"header\" in entry;\n\ntype ReportCompare = {\n\tdata: string;\n\texitCode: number;\n\texitMessage: string;\n\toutputFile: string;\n};\n\nexport const reportStats = async ({ flags }): Promise<ReportCompare> => {\n\tconst result: ReportCompare = {\n\t\texitCode: 0,\n\t\texitMessage: \"\",\n\t\toutputFile: \"\",\n\t\tdata: \"\",\n\t};\n\n\tlet previousStats, previousVersion: string;\n\tconst isValidConfigResult = validateConfigurationFile(flags.configuration);\n\tif (isValidConfigResult.exitMessage !== \"\") {\n\t\treturn { ...result, ...isValidConfigResult };\n\t}\n\n\tconst configurationFile = isValidConfigResult.data;\n\tconst outputFile = getOutputFile(flags.output);\n\tresult.outputFile = outputFile;\n\n\tconst configuration: {\n\t\treport: ReportConfiguration;\n\t\tsizes?: SizesConfiguration;\n\t} = await import(configurationFile).then((m) => m.default);\n\n\tconst currentStats = readJSONFile(\n\t\tjoin(dirname(configurationFile), configuration.report.current),\n\t);\n\tif (currentStats.exitMessage !== \"\") {\n\t\treturn { ...result, ...currentStats };\n\t}\n\n\ttry {\n\t\tpreviousStats = readJSONFile(\n\t\t\tjoin(dirname(configurationFile), configuration.report.previous),\n\t\t);\n\t\tif (previousStats.exitMessage !== \"\") {\n\t\t\treturn { ...result, ...previousStats };\n\t\t}\n\t\tpreviousVersion = getMostRecentVersion(previousStats.data);\n\t} catch {\n\t\t// no previous stats available.\n\t}\n\n\tconst currentVersion = getMostRecentVersion(currentStats.data);\n\n\tlet limitReached = false;\n\tlet overallDiff = 0;\n\tlet totalGzipSize = 0;\n\n\tconst threshold = configuration.report.threshold ?? DEFAULT_THRESHOLD;\n\tconst headerString = configuration.report.header || \"## Bundle Size\";\n\tconst footerFormatter = configuration.report.footer || formatFooter;\n\tconst columns = configuration.report.columns || [\n\t\t{ status: \"Status\" },\n\t\t{ file: \"File\" },\n\t\t{ size: \"Size (Gzip)\" },\n\t\t{ limits: \"Limits\" },\n\t];\n\n\tconst rowsMD: string[] = [];\n\tconst hasGroupHeaders = Boolean(configuration.sizes?.some(isHeaderEntry));\n\tif (!hasGroupHeaders) {\n\t\trowsMD.push(addMDrow({ type: \"header\", columns }));\n\t}\n\n\t// Build ordered keys based on configuration.sizes if present.\n\tconst orderedKeys: Array<{\n\t\ttype: \"header\" | \"item\";\n\t\tvalue: string;\n\t\theader?: string;\n\t}> = [];\n\tif (configuration.sizes && Array.isArray(configuration.sizes)) {\n\t\tfor (const entry of configuration.sizes) {\n\t\t\tif (isHeaderEntry(entry)) {\n\t\t\t\torderedKeys.push({ type: \"header\", value: \"\", header: entry.header });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// entry is FileSizeEntry here.\n\t\t\tif (entry.alias && currentStats.data[currentVersion][entry.alias]) {\n\t\t\t\torderedKeys.push({ type: \"item\", value: entry.alias });\n\t\t\t} else if (currentStats.data[currentVersion][entry.path]) {\n\t\t\t\torderedKeys.push({ type: \"item\", value: entry.path });\n\t\t\t}\n\t\t}\n\t}\n\n\tif (orderedKeys.length === 0) {\n\t\tfor (const key of Object.keys(currentStats.data[currentVersion])) {\n\t\t\torderedKeys.push({ type: \"item\", value: key });\n\t\t}\n\t}\n\n\tlet subGroupAccumulatedSize = 0;\n\tlet subGroupAccumulatedDiff = 0;\n\tlet subGroupAccumulatedPrevSize = 0;\n\tlet hasSubGroup = false;\n\tconst flushSubGroup = () => {\n\t\tif (!hasSubGroup) {\n\t\t\treturn;\n\t\t}\n\t\t// Use the accumulated thresholded diff directly\n\t\tconst diff = subGroupAccumulatedDiff;\n\t\tlet diffString = \"\";\n\t\tif (diff !== 0 && subGroupAccumulatedPrevSize !== 0) {\n\t\t\tconst sign = diff > 0 ? \"+\" : \"-\";\n\t\t\tdiffString = ` (${sign}${bytes(Math.abs(diff), { unitSeparator: \" \" })} ${percentFormatter(\n\t\t\t\tdiff / subGroupAccumulatedPrevSize,\n\t\t\t)})`;\n\t\t}\n\t\tif (hasGroupHeaders) {\n\t\t\trowsMD.push(\n\t\t\t\t`\\nSub-bundle size: ${bytes(subGroupAccumulatedSize, {\n\t\t\t\t\tunitSeparator: \" \",\n\t\t\t\t})}${diffString}`,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t}\n\t\tsubGroupAccumulatedSize = 0;\n\t\tsubGroupAccumulatedDiff = 0;\n\t\tsubGroupAccumulatedPrevSize = 0;\n\t\thasSubGroup = false;\n\t};\n\n\tfor (const entry of orderedKeys) {\n\t\tif (entry.type === \"header\") {\n\t\t\tflushSubGroup();\n\t\t\trowsMD.push(\"\", entry.header as string, \"\");\n\t\t\trowsMD.push(addMDrow({ type: \"header\", columns }));\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = entry.value;\n\t\tconst item = currentStats.data[currentVersion][key];\n\t\tif (!item) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = basename(key);\n\t\tif (!item.passed) {\n\t\t\tlimitReached = true;\n\t\t}\n\n\t\tlet diffString = \"\";\n\t\tlet previousFileSizeGzip = 0;\n\t\tlet thresholdedDiff = 0;\n\t\tif (previousStats && previousVersion) {\n\t\t\tconst previousFileStats =\n\t\t\t\tpreviousStats.data[previousVersion] &&\n\t\t\t\tpreviousStats.data[previousVersion][key];\n\t\t\tpreviousFileSizeGzip = previousFileStats?.fileSizeGzip || 0;\n\t\t\tlet diff = item.fileSizeGzip - previousFileSizeGzip;\n\t\t\t// Apply threshold: if the absolute diff is below threshold, treat as no change\n\t\t\tif (Math.abs(diff) < threshold) {\n\t\t\t\tdiff = 0;\n\t\t\t}\n\t\t\tthresholdedDiff = diff;\n\t\t\toverallDiff += diff;\n\t\t\tdiffString =\n\t\t\t\tdiff === 0 || diff === item.fileSizeGzip\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: ` (${diff > 0 ? \"+\" : \"-\"}${bytes(Math.abs(diff), { unitSeparator: \" \" })} ${percentFormatter(\n\t\t\t\t\t\t\tpreviousFileSizeGzip === 0 ? 0 : diff / previousFileSizeGzip,\n\t\t\t\t\t\t)})`;\n\t\t}\n\n\t\ttotalGzipSize += item.fileSizeGzip;\n\t\tsubGroupAccumulatedSize += item.fileSizeGzip;\n\t\tsubGroupAccumulatedDiff += thresholdedDiff;\n\t\tsubGroupAccumulatedPrevSize += previousFileSizeGzip;\n\t\thasSubGroup = true;\n\n\t\trowsMD.push(\n\t\t\taddMDrow({\n\t\t\t\ttype: \"row\",\n\t\t\t\tpassed: item.passed,\n\t\t\t\tname: name,\n\t\t\t\tsize: item.fileSizeGzip,\n\t\t\t\tdiff: diffString,\n\t\t\t\tlimit: item.limit,\n\t\t\t\tcolumns,\n\t\t\t}),\n\t\t);\n\t}\n\n\tflushSubGroup();\n\n\tconst template = `\n${headerString}\n${rowsMD.join(\"\\n\")}\n\n${footerFormatter({ limitReached, overallDiff, totalGzipSize })}\n`;\n\n\tif (limitReached) {\n\t\tresult.exitCode = 1;\n\t}\n\tresult.data = template;\n\treturn result;\n};\n"],"names":["basename","dirname","join","bytes","DEFAULT_THRESHOLD","addMDrow","formatFooter","getMostRecentVersion","getOutputFile","percentFormatter","readJSONFile","validateConfigurationFile","isHeaderEntry","entry","reportStats","flags","result","exitCode","exitMessage","outputFile","data","previousStats","previousVersion","isValidConfigResult","configuration","configurationFile","output","then","m","default","currentStats","report","current","previous","currentVersion","limitReached","overallDiff","totalGzipSize","threshold","headerString","header","footerFormatter","footer","columns","status","file","size","limits","rowsMD","hasGroupHeaders","Boolean","sizes","some","push","type","orderedKeys","Array","isArray","value","alias","path","length","key","Object","keys","subGroupAccumulatedSize","subGroupAccumulatedDiff","subGroupAccumulatedPrevSize","hasSubGroup","flushSubGroup","diff","diffString","sign","Math","abs","unitSeparator","item","name","passed","previousFileSizeGzip","thresholdedDiff","previousFileStats","fileSizeGzip","limit","template"],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "@node-cli/bundlesize",
3
- "version": "4.4.0",
3
+ "version": "4.5.1",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "description": "Simple CLI tool that checks file(s) size and report if limits have been reached",
7
7
  "type": "module",
8
8
  "types": "./dist/index.d.ts",
9
- "exports": "./dist/bundlesize.js",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/config.js"
13
+ }
14
+ },
10
15
  "bin": "dist/bundlesize.js",
11
16
  "files": [
12
17
  "dist",
@@ -45,5 +50,5 @@
45
50
  "@vitest/coverage-v8": "3.2.4",
46
51
  "vitest": "3.2.4"
47
52
  },
48
- "gitHead": "ffc82a19b07c42aa655d4a15e8e1459e1530ecdc"
53
+ "gitHead": "b19e02fcb4745190530c693093fe87a5af5517bf"
49
54
  }