rollup-plugin-stats 1.0.0 → 1.1.0-beta.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
@@ -3,7 +3,7 @@
3
3
  [![](https://img.shields.io/npm/v/rollup-plugin-stats.svg)](https://www.npmjs.com/package/rollup-plugin-stats)
4
4
  ![](https://img.shields.io/node/v/rollup-plugin-stats.svg)
5
5
  [![Socket Badge](https://socket.dev/api/badge/npm/package/rollup-plugin-stats)](https://socket.dev/npm/package/rollup-plugin-stats)
6
- [![CI](https://github.com/vio/rollup-plugin-stats/actions/workflows/main.yml/badge.svg)](https://github.com/vio/rollup-plugin-stats/actions/workflows/main.yml)
6
+ [![ci](https://github.com/vio/rollup-plugin-stats/actions/workflows/ci.yml/badge.svg)](https://github.com/vio/rollup-plugin-stats/actions/workflows/ci.yml)
7
7
 
8
8
  Output Rollup stats JSON file
9
9
 
@@ -47,6 +47,9 @@ module.exports = {
47
47
 
48
48
  ### Options
49
49
 
50
- - `fileName` - the JSON filename relative to the build folder, default: `stats.json`
50
+ - `fileName` - the JSON filepath relative to the build folder or absolute(default: `stats.json`)
51
+ - `write` - format and write the stats to disk(default: `fs.write(filename, JSON.stringify(stats, null, 2))`)
51
52
  - `stats`
52
53
  - `source` - output asset/chunk/module source (default `false`)
54
+ - `excludeAssets` - exclude matching assets: `string | RegExp | ((filepath: string) => boolean) | Array<string | RegExp | ((filepath: string) => boolean)>`
55
+ - `excludeModules` - exclude matching modules: `string | RegExp | ((filepath: string) => boolean) | Array<string | RegExp | ((filepath: string) => boolean)>`
package/dist/extract.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { OutputAsset, OutputBundle, OutputChunk, RenderedModule } from 'rollup';
2
+ import { type ExcludeFilepathPatterns } from './utils/check-exclude-filepath';
2
3
  export type AssetStats = Omit<OutputAsset, 'source'> & {
3
4
  source?: OutputAsset['source'];
4
5
  };
@@ -16,5 +17,13 @@ export type StatsOptions = {
16
17
  * @default false
17
18
  */
18
19
  source?: boolean;
20
+ /**
21
+ * Exclude matching assets
22
+ */
23
+ excludeAssets?: ExcludeFilepathPatterns;
24
+ /**
25
+ * Exclude matching modules
26
+ */
27
+ excludeModules?: ExcludeFilepathPatterns;
19
28
  };
20
29
  export default function extractRollupStats(bundle: OutputBundle, options?: StatsOptions): Stats;
package/dist/index.cjs CHANGED
@@ -1,59 +1,148 @@
1
1
  'use strict';
2
2
 
3
+ var path = require('node:path');
4
+ var process = require('node:process');
5
+ var fs = require('node:fs/promises');
3
6
  var omit = require('lodash/omit.js');
7
+ var entries = require('lodash/entries.js');
8
+ var round = require('lodash/round.js');
9
+
10
+ /**
11
+ * Check if filepath should be excluded based on patterns
12
+ */
13
+ function checkExcludeFilepath(filepath, patterns) {
14
+ if (!patterns) {
15
+ return false;
16
+ }
17
+ if (Array.isArray(patterns)) {
18
+ let res = false;
19
+ for (let i = 0; i <= patterns.length - 1 && res === false; i++) {
20
+ res = checkExcludeFilepath(filepath, patterns[i]);
21
+ }
22
+ return res;
23
+ }
24
+ if (typeof patterns === 'function') {
25
+ return patterns(filepath);
26
+ }
27
+ if (typeof patterns === 'string') {
28
+ return Boolean(filepath.match(patterns));
29
+ }
30
+ if ('test' in patterns) {
31
+ return patterns.test(filepath);
32
+ }
33
+ return false;
34
+ }
4
35
 
5
36
  function extractRollupStats(bundle, options = {}) {
6
- const { source = false } = options;
37
+ const { source = false, excludeAssets, excludeModules } = options;
7
38
  const output = {};
8
- Object.entries(bundle).forEach(([key, entry]) => {
9
- if (entry.type === "asset") {
10
- let entryAsset = structuredClone(entry);
11
- // Skip asset source if options.source is false
39
+ entries(bundle).forEach(([bundleEntryFilepath, bundleEntryStats]) => {
40
+ // Skip extraction if the entry filepath matches the exclude assets pattern
41
+ if (checkExcludeFilepath(bundleEntryFilepath, excludeAssets)) {
42
+ return;
43
+ }
44
+ if (bundleEntryStats.type === "asset") {
45
+ let assetStats = structuredClone(bundleEntryStats);
46
+ // Skip asset source if options source is false
12
47
  if (!source) {
13
- entryAsset = omit(entryAsset, 'source');
48
+ assetStats = omit(assetStats, 'source');
14
49
  }
15
- output[key] = entryAsset;
50
+ output[bundleEntryFilepath] = assetStats;
16
51
  return;
17
52
  }
18
- if (entry.type === "chunk") {
19
- let entryChunk = structuredClone(entry);
20
- // Skip chunk code if options.source is false
53
+ if (bundleEntryStats.type === "chunk") {
54
+ let chunkStats = structuredClone(bundleEntryStats);
55
+ // Skip chunk source if options source is false
21
56
  if (!source) {
22
- entryChunk = omit(entryChunk, 'code');
57
+ chunkStats = omit(chunkStats, 'code');
23
58
  }
24
- Object.entries(entryChunk.modules).forEach(([moduleKey, moduleEntry]) => {
25
- let entryChunkModule = structuredClone(moduleEntry);
26
- // Skip module source if source is false
59
+ // Extract chunk modules stats
60
+ const chunkModulesStats = {};
61
+ entries(chunkStats.modules).forEach(([bundleModuleFilepath, bundleModuleStats]) => {
62
+ // Skip module extraction if the filepath matches the exclude modules pattern
63
+ if (checkExcludeFilepath(bundleModuleFilepath, excludeModules)) {
64
+ return;
65
+ }
66
+ let moduleStats = structuredClone(bundleModuleStats);
67
+ // Skip module source if options source is false
27
68
  if (!source) {
28
- entryChunkModule = omit(entryChunkModule, 'code');
69
+ moduleStats = omit(moduleStats, 'code');
29
70
  }
30
- entryChunk.modules[moduleKey] = entryChunkModule;
71
+ chunkModulesStats[bundleModuleFilepath] = moduleStats;
31
72
  });
32
- output[key] = entryChunk;
73
+ chunkStats.modules = chunkModulesStats;
74
+ output[bundleEntryFilepath] = chunkStats;
33
75
  return;
34
76
  }
35
77
  });
36
78
  return output;
37
79
  }
38
80
 
81
+ const FILE_SIZE = {
82
+ BYTE: {
83
+ symbol: 'B',
84
+ multiplier: 1,
85
+ },
86
+ KILO: {
87
+ symbol: 'KiB',
88
+ multiplier: 1024,
89
+ },
90
+ MEGA: {
91
+ symbol: 'MiB',
92
+ multiplier: 1024 * 1024,
93
+ },
94
+ };
95
+ function formatFileSize(value) {
96
+ let unit = FILE_SIZE.BYTE;
97
+ if (typeof value !== 'number') {
98
+ return `0${unit.symbol}`;
99
+ }
100
+ if (value < FILE_SIZE.KILO.multiplier) {
101
+ unit = FILE_SIZE.BYTE;
102
+ }
103
+ else if (value < FILE_SIZE.MEGA.multiplier) {
104
+ unit = FILE_SIZE.KILO;
105
+ }
106
+ else {
107
+ unit = FILE_SIZE.MEGA;
108
+ }
109
+ return `${round(value / unit.multiplier, 2)}${unit.symbol}`;
110
+ }
111
+
39
112
  const PLUGIN_NAME = 'rollupStats';
40
113
  const DEFAULT_FILE_NAME = 'stats.json';
41
- function defaultFormatOutput(stats) {
42
- return JSON.stringify(stats, null, 2);
43
- }
44
114
  function rollupStats(options = {}) {
45
- const { fileName, stats } = options;
115
+ const { fileName, stats: statsOptions, writer = rollupStatsWrite } = options;
46
116
  return {
47
117
  name: PLUGIN_NAME,
48
- generateBundle(_, bundle) {
49
- this.emitFile({
50
- type: 'asset',
51
- fileName: fileName || DEFAULT_FILE_NAME,
52
- source: defaultFormatOutput(extractRollupStats(bundle, stats)),
53
- });
118
+ async generateBundle(context, bundle) {
119
+ const resolvedFileName = fileName || DEFAULT_FILE_NAME;
120
+ const filepath = path.isAbsolute(resolvedFileName)
121
+ ? resolvedFileName
122
+ : path.join(context.dir || process.cwd(), resolvedFileName);
123
+ const stats = extractRollupStats(bundle, statsOptions);
124
+ try {
125
+ const res = await writer(filepath, stats);
126
+ const outputSize = Buffer.byteLength(res.content, 'utf-8');
127
+ this.info(`Stats saved to ${res.filepath} (${formatFileSize(outputSize)})`);
128
+ }
129
+ catch (error) {
130
+ // Log error, but do not throw to allow the compilation to continue
131
+ this.warn(error);
132
+ }
54
133
  },
55
134
  };
56
135
  }
136
+ async function rollupStatsWrite(filepath, stats) {
137
+ const content = JSON.stringify(stats, null, 2);
138
+ // Create base directory if it does not exist
139
+ await fs.mkdir(path.dirname(filepath), { recursive: true });
140
+ await fs.writeFile(filepath, content);
141
+ return {
142
+ filepath,
143
+ content,
144
+ };
145
+ }
57
146
 
58
147
  module.exports = rollupStats;
59
148
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/extract.ts","../src/index.ts"],"sourcesContent":[null,null],"names":[],"mappings":";;;;AA0BwB,SAAA,kBAAkB,CAAC,MAAoB,EAAE,UAAwB,EAAE,EAAA;AACzF,IAAA,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO;IAElC,MAAM,MAAM,GAAU,EAAE;AAExB,IAAA,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;AAC9C,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;AAC1B,YAAA,IAAI,UAAU,GAAG,eAAe,CAAC,KAAK,CAAe;;YAGrD,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;;AAGzC,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU;YAExB;;AAGF,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;AAC1B,YAAA,IAAI,UAAU,GAAG,eAAe,CAAC,KAAK,CAAe;;YAGrD,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC;;AAGvC,YAAA,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,KAAI;AACtE,gBAAA,IAAI,gBAAgB,GAAG,eAAe,CAAC,WAAW,CAAgB;;gBAGlE,IAAI,CAAC,MAAM,EAAE;AACX,oBAAA,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC;;AAGnD,gBAAA,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,gBAAgB;AAClD,aAAC,CAAC;AAEF,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU;YAExB;;AAEJ,KAAC,CAAC;AAEF,IAAA,OAAO,MAAM;AACf;;ACnEA,MAAM,WAAW,GAAG,aAAa;AACjC,MAAM,iBAAiB,GAAG,YAAY;AAEtC,SAAS,mBAAmB,CAAC,KAAc,EAAA;IACzC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvC;AAWA,SAAS,WAAW,CAAC,OAAA,GAA8B,EAAE,EAAA;AACnD,IAAA,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO;IAEnC,OAAO;AACL,QAAA,IAAI,EAAE,WAAW;QACjB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAA;YACtB,IAAI,CAAC,QAAQ,CAAC;AACZ,gBAAA,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,QAAQ,IAAI,iBAAiB;gBACvC,MAAM,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC/D,aAAA,CAAC;SACH;KACe;AACpB;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/utils/check-exclude-filepath.ts","../src/extract.ts","../src/utils/format-file-size.ts","../src/index.ts"],"sourcesContent":[null,null,null,null],"names":[],"mappings":";;;;;;;;;AAIA;;AAEG;AACa,SAAA,oBAAoB,CAClC,QAAgB,EAChB,QAAkC,EAAA;IAElC,IAAI,CAAC,QAAQ,EAAE;AACb,QAAA,OAAO,KAAK;;AAGd,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QAC3B,IAAI,GAAG,GAAG,KAAK;QAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC,EAAE,EAAE;YAC9D,GAAG,GAAG,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;;AAGnD,QAAA,OAAO,GAAG;;AAGZ,IAAA,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;AAClC,QAAA,OAAO,QAAQ,CAAC,QAAQ,CAAC;;AAG3B,IAAA,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;QAChC,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;;AAG1C,IAAA,IAAI,MAAM,IAAI,QAAQ,EAAE;AACtB,QAAA,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;;AAGhC,IAAA,OAAO,KAAK;AACd;;ACFwB,SAAA,kBAAkB,CAAC,MAAoB,EAAE,UAAwB,EAAE,EAAA;IACzF,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,OAAO;IAEjE,MAAM,MAAM,GAAU,EAAE;AAExB,IAAA,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,KAAI;;AAElE,QAAA,IAAI,oBAAoB,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAAE;YAC5D;;AAGF,QAAA,IAAI,gBAAgB,CAAC,IAAI,KAAK,OAAO,EAAE;AACrC,YAAA,IAAI,UAAU,GAAG,eAAe,CAAC,gBAAgB,CAAe;;YAGhE,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;;AAGzC,YAAA,MAAM,CAAC,mBAAmB,CAAC,GAAG,UAAU;YAExC;;AAGF,QAAA,IAAI,gBAAgB,CAAC,IAAI,KAAK,OAAO,EAAE;AACrC,YAAA,IAAI,UAAU,GAAG,eAAe,CAAC,gBAAgB,CAAe;;YAGhE,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC;;;YAIvC,MAAM,iBAAiB,GAA0B,EAAE;AAEnD,YAAA,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,KAAI;;AAEhF,gBAAA,IAAI,oBAAoB,CAAC,oBAAoB,EAAE,cAAc,CAAC,EAAE;oBAC9D;;AAGF,gBAAA,IAAI,WAAW,GAAG,eAAe,CAAC,iBAAiB,CAAgB;;gBAGnE,IAAI,CAAC,MAAM,EAAE;AACX,oBAAA,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;;AAGzC,gBAAA,iBAAiB,CAAC,oBAAoB,CAAC,GAAG,WAAW;AACvD,aAAC,CAAC;AAEF,YAAA,UAAU,CAAC,OAAO,GAAG,iBAAiB;AAEtC,YAAA,MAAM,CAAC,mBAAmB,CAAC,GAAG,UAAU;YAExC;;AAEJ,KAAC,CAAC;AAEF,IAAA,OAAO,MAAM;AACf;;AC9FA,MAAM,SAAS,GAAG;AAChB,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,UAAU,EAAE,CAAC;AACd,KAAA;AACD,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,KAAK;AACb,QAAA,UAAU,EAAE,IAAI;AACjB,KAAA;AACD,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,KAAK;QACb,UAAU,EAAE,IAAI,GAAG,IAAI;AACxB,KAAA;CACF;AAEK,SAAU,cAAc,CAAC,KAAqB,EAAA;AAClD,IAAA,IAAI,IAAI,GAAG,SAAS,CAAC,IAAI;AAEzB,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,QAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAAC,MAAM,EAAE;;IAG1B,IAAI,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE;AACrC,QAAA,IAAI,GAAG,SAAS,CAAC,IAAI;;SAChB,IAAI,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE;AAC5C,QAAA,IAAI,GAAG,SAAS,CAAC,IAAI;;SAChB;AACL,QAAA,IAAI,GAAG,SAAS,CAAC,IAAI;;AAGvB,IAAA,OAAO,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAG,EAAA,IAAI,CAAC,MAAM,EAAE;AAC7D;;ACzBA,MAAM,WAAW,GAAG,aAAa;AACjC,MAAM,iBAAiB,GAAG,YAAY;AA0BtC,SAAS,WAAW,CAAC,OAAA,GAA8B,EAAE,EAAA;AACnD,IAAA,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,OAAO;IAE5E,OAAO;AACL,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,EAAA;AAClC,YAAA,MAAM,gBAAgB,GAAG,QAAQ,IAAI,iBAAiB;AACtD,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB;AAC/C,kBAAE;AACF,kBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC;YAE7D,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,YAAY,CAAC;AAEtD,YAAA,IAAI;gBACF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC;AACzC,gBAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;AAE1D,gBAAA,IAAI,CAAC,IAAI,CAAC,CAAA,eAAA,EAAkB,GAAG,CAAC,QAAQ,CAAK,EAAA,EAAA,cAAc,CAAC,UAAU,CAAC,CAAA,CAAA,CAAG,CAAC;;YAC3E,OAAO,KAAK,EAAE;;AAEd,gBAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;SAEnB;KACe;AACpB;AAIA,eAAe,gBAAgB,CAAC,QAAgB,EAAE,KAAY,EAAA;AAC5D,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;;AAG9C,IAAA,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAE3D,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;IAErC,OAAO;QACL,QAAQ;QACR,OAAO;KACR;AACH;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,25 @@
1
- import { Plugin } from 'rollup';
2
- import { type StatsOptions } from './extract';
1
+ import type { Plugin } from 'rollup';
2
+ import { type Stats, type StatsOptions } from './extract';
3
+ export type RollupStatsWriteResponse = {
4
+ filepath: string;
5
+ content: string;
6
+ };
7
+ export type RollupStatsWrite = (filepath: string, stats: Stats) => RollupStatsWriteResponse;
3
8
  export type RollupStatsOptions = {
4
9
  /**
5
- * JSON file output fileName
6
- * default: stats.json
10
+ * Output filename relative to Rollup output directory or absolute
11
+ * @default: stats.json
7
12
  */
8
13
  fileName?: string;
14
+ /**
15
+ * Rollup stats options
16
+ */
9
17
  stats?: StatsOptions;
18
+ /**
19
+ * Custom file writer
20
+ * @default - fs.write(FILENAME, JSON.stringify(STATS, null, 2));
21
+ */
22
+ write?: RollupStatsWrite;
10
23
  };
11
24
  declare function rollupStats(options?: RollupStatsOptions): Plugin;
12
25
  export default rollupStats;
package/dist/index.mjs CHANGED
@@ -1,57 +1,146 @@
1
+ import path from 'node:path';
2
+ import process from 'node:process';
3
+ import fs from 'node:fs/promises';
1
4
  import omit from 'lodash/omit.js';
5
+ import entries from 'lodash/entries.js';
6
+ import round from 'lodash/round.js';
7
+
8
+ /**
9
+ * Check if filepath should be excluded based on patterns
10
+ */
11
+ function checkExcludeFilepath(filepath, patterns) {
12
+ if (!patterns) {
13
+ return false;
14
+ }
15
+ if (Array.isArray(patterns)) {
16
+ let res = false;
17
+ for (let i = 0; i <= patterns.length - 1 && res === false; i++) {
18
+ res = checkExcludeFilepath(filepath, patterns[i]);
19
+ }
20
+ return res;
21
+ }
22
+ if (typeof patterns === 'function') {
23
+ return patterns(filepath);
24
+ }
25
+ if (typeof patterns === 'string') {
26
+ return Boolean(filepath.match(patterns));
27
+ }
28
+ if ('test' in patterns) {
29
+ return patterns.test(filepath);
30
+ }
31
+ return false;
32
+ }
2
33
 
3
34
  function extractRollupStats(bundle, options = {}) {
4
- const { source = false } = options;
35
+ const { source = false, excludeAssets, excludeModules } = options;
5
36
  const output = {};
6
- Object.entries(bundle).forEach(([key, entry]) => {
7
- if (entry.type === "asset") {
8
- let entryAsset = structuredClone(entry);
9
- // Skip asset source if options.source is false
37
+ entries(bundle).forEach(([bundleEntryFilepath, bundleEntryStats]) => {
38
+ // Skip extraction if the entry filepath matches the exclude assets pattern
39
+ if (checkExcludeFilepath(bundleEntryFilepath, excludeAssets)) {
40
+ return;
41
+ }
42
+ if (bundleEntryStats.type === "asset") {
43
+ let assetStats = structuredClone(bundleEntryStats);
44
+ // Skip asset source if options source is false
10
45
  if (!source) {
11
- entryAsset = omit(entryAsset, 'source');
46
+ assetStats = omit(assetStats, 'source');
12
47
  }
13
- output[key] = entryAsset;
48
+ output[bundleEntryFilepath] = assetStats;
14
49
  return;
15
50
  }
16
- if (entry.type === "chunk") {
17
- let entryChunk = structuredClone(entry);
18
- // Skip chunk code if options.source is false
51
+ if (bundleEntryStats.type === "chunk") {
52
+ let chunkStats = structuredClone(bundleEntryStats);
53
+ // Skip chunk source if options source is false
19
54
  if (!source) {
20
- entryChunk = omit(entryChunk, 'code');
55
+ chunkStats = omit(chunkStats, 'code');
21
56
  }
22
- Object.entries(entryChunk.modules).forEach(([moduleKey, moduleEntry]) => {
23
- let entryChunkModule = structuredClone(moduleEntry);
24
- // Skip module source if source is false
57
+ // Extract chunk modules stats
58
+ const chunkModulesStats = {};
59
+ entries(chunkStats.modules).forEach(([bundleModuleFilepath, bundleModuleStats]) => {
60
+ // Skip module extraction if the filepath matches the exclude modules pattern
61
+ if (checkExcludeFilepath(bundleModuleFilepath, excludeModules)) {
62
+ return;
63
+ }
64
+ let moduleStats = structuredClone(bundleModuleStats);
65
+ // Skip module source if options source is false
25
66
  if (!source) {
26
- entryChunkModule = omit(entryChunkModule, 'code');
67
+ moduleStats = omit(moduleStats, 'code');
27
68
  }
28
- entryChunk.modules[moduleKey] = entryChunkModule;
69
+ chunkModulesStats[bundleModuleFilepath] = moduleStats;
29
70
  });
30
- output[key] = entryChunk;
71
+ chunkStats.modules = chunkModulesStats;
72
+ output[bundleEntryFilepath] = chunkStats;
31
73
  return;
32
74
  }
33
75
  });
34
76
  return output;
35
77
  }
36
78
 
79
+ const FILE_SIZE = {
80
+ BYTE: {
81
+ symbol: 'B',
82
+ multiplier: 1,
83
+ },
84
+ KILO: {
85
+ symbol: 'KiB',
86
+ multiplier: 1024,
87
+ },
88
+ MEGA: {
89
+ symbol: 'MiB',
90
+ multiplier: 1024 * 1024,
91
+ },
92
+ };
93
+ function formatFileSize(value) {
94
+ let unit = FILE_SIZE.BYTE;
95
+ if (typeof value !== 'number') {
96
+ return `0${unit.symbol}`;
97
+ }
98
+ if (value < FILE_SIZE.KILO.multiplier) {
99
+ unit = FILE_SIZE.BYTE;
100
+ }
101
+ else if (value < FILE_SIZE.MEGA.multiplier) {
102
+ unit = FILE_SIZE.KILO;
103
+ }
104
+ else {
105
+ unit = FILE_SIZE.MEGA;
106
+ }
107
+ return `${round(value / unit.multiplier, 2)}${unit.symbol}`;
108
+ }
109
+
37
110
  const PLUGIN_NAME = 'rollupStats';
38
111
  const DEFAULT_FILE_NAME = 'stats.json';
39
- function defaultFormatOutput(stats) {
40
- return JSON.stringify(stats, null, 2);
41
- }
42
112
  function rollupStats(options = {}) {
43
- const { fileName, stats } = options;
113
+ const { fileName, stats: statsOptions, writer = rollupStatsWrite } = options;
44
114
  return {
45
115
  name: PLUGIN_NAME,
46
- generateBundle(_, bundle) {
47
- this.emitFile({
48
- type: 'asset',
49
- fileName: fileName || DEFAULT_FILE_NAME,
50
- source: defaultFormatOutput(extractRollupStats(bundle, stats)),
51
- });
116
+ async generateBundle(context, bundle) {
117
+ const resolvedFileName = fileName || DEFAULT_FILE_NAME;
118
+ const filepath = path.isAbsolute(resolvedFileName)
119
+ ? resolvedFileName
120
+ : path.join(context.dir || process.cwd(), resolvedFileName);
121
+ const stats = extractRollupStats(bundle, statsOptions);
122
+ try {
123
+ const res = await writer(filepath, stats);
124
+ const outputSize = Buffer.byteLength(res.content, 'utf-8');
125
+ this.info(`Stats saved to ${res.filepath} (${formatFileSize(outputSize)})`);
126
+ }
127
+ catch (error) {
128
+ // Log error, but do not throw to allow the compilation to continue
129
+ this.warn(error);
130
+ }
52
131
  },
53
132
  };
54
133
  }
134
+ async function rollupStatsWrite(filepath, stats) {
135
+ const content = JSON.stringify(stats, null, 2);
136
+ // Create base directory if it does not exist
137
+ await fs.mkdir(path.dirname(filepath), { recursive: true });
138
+ await fs.writeFile(filepath, content);
139
+ return {
140
+ filepath,
141
+ content,
142
+ };
143
+ }
55
144
 
56
145
  export { rollupStats as default };
57
146
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/extract.ts","../src/index.ts"],"sourcesContent":[null,null],"names":[],"mappings":";;AA0BwB,SAAA,kBAAkB,CAAC,MAAoB,EAAE,UAAwB,EAAE,EAAA;AACzF,IAAA,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO;IAElC,MAAM,MAAM,GAAU,EAAE;AAExB,IAAA,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;AAC9C,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;AAC1B,YAAA,IAAI,UAAU,GAAG,eAAe,CAAC,KAAK,CAAe;;YAGrD,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;;AAGzC,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU;YAExB;;AAGF,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;AAC1B,YAAA,IAAI,UAAU,GAAG,eAAe,CAAC,KAAK,CAAe;;YAGrD,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC;;AAGvC,YAAA,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,KAAI;AACtE,gBAAA,IAAI,gBAAgB,GAAG,eAAe,CAAC,WAAW,CAAgB;;gBAGlE,IAAI,CAAC,MAAM,EAAE;AACX,oBAAA,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC;;AAGnD,gBAAA,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,gBAAgB;AAClD,aAAC,CAAC;AAEF,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU;YAExB;;AAEJ,KAAC,CAAC;AAEF,IAAA,OAAO,MAAM;AACf;;ACnEA,MAAM,WAAW,GAAG,aAAa;AACjC,MAAM,iBAAiB,GAAG,YAAY;AAEtC,SAAS,mBAAmB,CAAC,KAAc,EAAA;IACzC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvC;AAWA,SAAS,WAAW,CAAC,OAAA,GAA8B,EAAE,EAAA;AACnD,IAAA,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO;IAEnC,OAAO;AACL,QAAA,IAAI,EAAE,WAAW;QACjB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAA;YACtB,IAAI,CAAC,QAAQ,CAAC;AACZ,gBAAA,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,QAAQ,IAAI,iBAAiB;gBACvC,MAAM,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC/D,aAAA,CAAC;SACH;KACe;AACpB;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/utils/check-exclude-filepath.ts","../src/extract.ts","../src/utils/format-file-size.ts","../src/index.ts"],"sourcesContent":[null,null,null,null],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ type ExcludeFilepathParam = string | RegExp | ((filepath: string) => boolean);
2
+ export type ExcludeFilepathPatterns = ExcludeFilepathParam | Array<ExcludeFilepathParam>;
3
+ /**
4
+ * Check if filepath should be excluded based on patterns
5
+ */
6
+ export declare function checkExcludeFilepath(filepath: string, patterns?: ExcludeFilepathPatterns): boolean;
7
+ export {};
@@ -0,0 +1 @@
1
+ export declare function formatFileSize(value?: number | null): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rollup-plugin-stats",
3
3
  "description": "Output Rollup stats",
4
- "version": "1.0.0",
4
+ "version": "1.1.0-beta.1",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "author": {
@@ -59,6 +59,7 @@
59
59
  "eslint": "^9.17.0",
60
60
  "globals": "^15.14.0",
61
61
  "husky": "^8.0.3",
62
+ "memfs": "^4.15.1",
62
63
  "prettier": "^3.4.2",
63
64
  "release-it": "17.10.0",
64
65
  "rollup": "^4.29.1",