rollup-plugin-webpack-stats 3.1.0 → 3.1.1-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/dist/src/plugin.cjs.map +1 -1
- package/dist/src/plugin.d.cts +34 -1
- package/dist/src/plugin.d.cts.map +1 -1
- package/dist/src/plugin.d.mts +34 -1
- package/dist/src/plugin.d.mts.map +1 -1
- package/dist/src/plugin.mjs.map +1 -1
- package/dist/transform.cjs +10 -4
- package/dist/transform.cjs.map +1 -1
- package/dist/transform.d.cts +1 -1
- package/dist/transform.d.cts.map +1 -1
- package/dist/transform.d.mts +1 -1
- package/dist/transform.d.mts.map +1 -1
- package/dist/transform.mjs +10 -4
- package/dist/transform.mjs.map +1 -1
- package/package.json +2 -4
- package/dist/src/types.d.cts +0 -9
- package/dist/src/types.d.cts.map +0 -1
- package/dist/src/types.d.mts +0 -9
- package/dist/src/types.d.mts.map +0 -1
package/dist/src/plugin.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs","names":["statsWrite","bundleToWebpackStats","resolveFilepath","getByteSize","formatFileSize"],"sources":["../../src/plugin.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"plugin.cjs","names":["statsWrite","bundleToWebpackStats","resolveFilepath","getByteSize","formatFileSize"],"sources":["../../src/plugin.ts"],"sourcesContent":["import type { OutputBundle } from 'rollup-plugin-stats';\nimport extractStats, { type StatsOptions } from 'rollup-plugin-stats/extract';\n\nimport { type BundleTransformOptions, bundleToWebpackStats } from './transform';\nimport { type StatsWrite, statsWrite } from './write';\nimport { formatFileSize, getByteSize, resolveFilepath } from './utils';\n\nconst PLUGIN_NAME = 'webpackStats';\n\n/**\n * A subset of resolved output options provided to the `generateBundle` hook by Vite/Rolldown/Rollup,\n * containing only the fields this plugin uses to generate a stats file for a specific output.\n */\nexport type OutputOptions = {\n /** Output directory for the generated files. */\n dir?: string | undefined;\n\n /** Output format */\n format?:\n | 'es'\n | 'esm'\n | 'module'\n | 'cjs'\n | 'commonjs'\n | 'iife'\n | 'umd'\n | 'amd'\n | 'system'\n | 'systemjs'\n | undefined;\n};\n\n/**\n * Subset of the Vite/Rolldown/Rollup plugin hook context (`this`) used by this plugin.\n */\ntype PluginContext = {\n /** Log an informational message through Vite/Rolldown/Rollup's logging pipeline. */\n info: (message: string) => void;\n\n /** Log a warning through Vite/Rolldown/Rollup's logging pipeline without stopping the build. */\n warn: (message: string) => void;\n};\n\n/**\n * Minimum plugin interface compatible with Vite/Rolldown/Rollup.\n *\n * @example\n * {\n * name: 'rollupStats',\n * async generateBundle(outputOptions, bundle) { ... },\n * }\n */\nexport type Plugin = {\n /** Unique identifier for the plugin, used in error messages and logs. */\n name: string;\n\n /**\n * Hook called after the bundle has been fully generated but before it is\n * written to disk. Receives the resolved output options and the complete\n * output bundle map.\n */\n generateBundle?: (\n this: PluginContext,\n outputOptions: OutputOptions,\n bundle: OutputBundle,\n isWrite: boolean\n ) => void | Promise<void>;\n};\n\ntype WebpackStatsOptions = {\n /**\n * JSON file output fileName\n * default: webpack-stats.json\n */\n fileName?: string;\n /**\n * Custom file writer\n * @default - fs.write(FILENAME, JSON.stringify(STATS, null, 2));\n */\n write?: StatsWrite;\n} & Omit<StatsOptions, 'source' | 'map'> &\n BundleTransformOptions;\n\ntype WebpackStatsOptionsOrBuilder =\n | WebpackStatsOptions\n | ((outputOptions: OutputOptions) => WebpackStatsOptions);\n\nexport const webpackStats = (\n options: WebpackStatsOptionsOrBuilder = {}\n): Plugin => ({\n name: PLUGIN_NAME,\n async generateBundle(outputOptions, bundle) {\n const resolvedOptions =\n typeof options === 'function' ? options(outputOptions) : options;\n const {\n fileName,\n excludeAssets,\n excludeModules,\n write = statsWrite,\n ...transformOptions\n } = resolvedOptions;\n\n const rollupStats = extractStats(bundle, {\n excludeAssets,\n excludeModules,\n // Extract stats source to compute size\n source: true,\n });\n const stats = bundleToWebpackStats(rollupStats, transformOptions);\n const filepath = resolveFilepath(fileName, outputOptions.dir);\n\n try {\n const res = await write(\n filepath,\n stats as unknown as Record<string, unknown>\n );\n const outputSize = getByteSize(res.content);\n\n this.info(\n `Stats saved to ${res.filepath} (${formatFileSize(outputSize)})`\n );\n } catch (error: unknown) {\n const message =\n error instanceof Error ? error.message : JSON.stringify(error);\n\n // Log error, but do not throw to allow the compilation to continue\n this.warn(message);\n }\n },\n});\n"],"mappings":";;;;;;;;AAOA,MAAM,cAAc;AAgFpB,MAAa,gBACX,UAAwC,EAAE,MAC9B;CACZ,MAAM;CACN,MAAM,eAAe,eAAe,QAAQ;EAG1C,MAAM,EACJ,UACA,eACA,gBACA,QAAQA,0BACR,GAAG,qBANH,OAAO,YAAY,aAAa,QAAQ,cAAc,GAAG;EAe3D,MAAM,QAAQC,gFANmB,QAAQ;GACvC;GACA;GAEA,QAAQ;GACT,CAAC,EAC8C,iBAAiB;EACjE,MAAM,WAAWC,8BAAgB,UAAU,cAAc,IAAI;AAE7D,MAAI;GACF,MAAM,MAAM,MAAM,MAChB,UACA,MACD;GACD,MAAM,aAAaC,0BAAY,IAAI,QAAQ;AAE3C,QAAK,KACH,kBAAkB,IAAI,SAAS,IAAIC,6BAAe,WAAW,CAAC,GAC/D;WACM,OAAgB;GACvB,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU,KAAK,UAAU,MAAM;AAGhE,QAAK,KAAK,QAAQ;;;CAGvB"}
|
package/dist/src/plugin.d.cts
CHANGED
|
@@ -1,9 +1,42 @@
|
|
|
1
|
-
import { OutputOptions, Plugin } from "./types.cjs";
|
|
2
1
|
import { BundleTransformOptions } from "../transform.cjs";
|
|
3
2
|
import { StatsWrite } from "./write.cjs";
|
|
3
|
+
import { OutputBundle } from "rollup-plugin-stats";
|
|
4
4
|
import { StatsOptions } from "rollup-plugin-stats/extract";
|
|
5
5
|
|
|
6
6
|
//#region src/plugin.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* A subset of resolved output options provided to the `generateBundle` hook by Vite/Rolldown/Rollup,
|
|
9
|
+
* containing only the fields this plugin uses to generate a stats file for a specific output.
|
|
10
|
+
*/
|
|
11
|
+
type OutputOptions = {
|
|
12
|
+
/** Output directory for the generated files. */dir?: string | undefined; /** Output format */
|
|
13
|
+
format?: 'es' | 'esm' | 'module' | 'cjs' | 'commonjs' | 'iife' | 'umd' | 'amd' | 'system' | 'systemjs' | undefined;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Subset of the Vite/Rolldown/Rollup plugin hook context (`this`) used by this plugin.
|
|
17
|
+
*/
|
|
18
|
+
type PluginContext = {
|
|
19
|
+
/** Log an informational message through Vite/Rolldown/Rollup's logging pipeline. */info: (message: string) => void; /** Log a warning through Vite/Rolldown/Rollup's logging pipeline without stopping the build. */
|
|
20
|
+
warn: (message: string) => void;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Minimum plugin interface compatible with Vite/Rolldown/Rollup.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* {
|
|
27
|
+
* name: 'rollupStats',
|
|
28
|
+
* async generateBundle(outputOptions, bundle) { ... },
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
type Plugin = {
|
|
32
|
+
/** Unique identifier for the plugin, used in error messages and logs. */name: string;
|
|
33
|
+
/**
|
|
34
|
+
* Hook called after the bundle has been fully generated but before it is
|
|
35
|
+
* written to disk. Receives the resolved output options and the complete
|
|
36
|
+
* output bundle map.
|
|
37
|
+
*/
|
|
38
|
+
generateBundle?: (this: PluginContext, outputOptions: OutputOptions, bundle: OutputBundle, isWrite: boolean) => void | Promise<void>;
|
|
39
|
+
};
|
|
7
40
|
type WebpackStatsOptions = {
|
|
8
41
|
/**
|
|
9
42
|
* JSON file output fileName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.cts","names":[],"sources":["../../src/plugin.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.cts","names":[],"sources":["../../src/plugin.ts"],"mappings":";;;;;;;;AAaA;;KAAY,aAAA;EAEV,gDAAA,GAAA,uBAoBG;EAjBH,MAAA;AAAA;;;;KAiBG,aAAA;EAKI,oFAHP,IAAA,GAAO,OAAA,mBAGe;EAAtB,IAAA,GAAO,OAAA;AAAA;;;;;;;;;;KAYG,MAAA;EAUR,yEARF,IAAA;EASE;;;;;EAFF,cAAA,IACE,IAAA,EAAM,aAAA,EACN,aAAA,EAAe,aAAA,EACf,MAAA,EAAQ,YAAA,EACR,OAAA,qBACU,OAAA;AAAA;AAAA,KAGT,mBAAA;EAAmB;;;;EAKtB,QAAA;EAOA;;;;EAFA,KAAA,GAAQ,UAAA;AAAA,IACN,IAAA,CAAK,YAAA,sBACP,sBAAA;AAAA,KAEG,4BAAA,GACD,mBAAA,KACE,aAAA,EAAe,aAAA,KAAkB,mBAAA;AAAA,cAE1B,YAAA,GACX,OAAA,GAAS,4BAAA,KACR,MAAA"}
|
package/dist/src/plugin.d.mts
CHANGED
|
@@ -1,9 +1,42 @@
|
|
|
1
|
-
import { OutputOptions, Plugin } from "./types.mjs";
|
|
2
1
|
import { BundleTransformOptions } from "../transform.mjs";
|
|
3
2
|
import { StatsWrite } from "./write.mjs";
|
|
4
3
|
import { StatsOptions } from "rollup-plugin-stats/extract";
|
|
4
|
+
import { OutputBundle } from "rollup-plugin-stats";
|
|
5
5
|
|
|
6
6
|
//#region src/plugin.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* A subset of resolved output options provided to the `generateBundle` hook by Vite/Rolldown/Rollup,
|
|
9
|
+
* containing only the fields this plugin uses to generate a stats file for a specific output.
|
|
10
|
+
*/
|
|
11
|
+
type OutputOptions = {
|
|
12
|
+
/** Output directory for the generated files. */dir?: string | undefined; /** Output format */
|
|
13
|
+
format?: 'es' | 'esm' | 'module' | 'cjs' | 'commonjs' | 'iife' | 'umd' | 'amd' | 'system' | 'systemjs' | undefined;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Subset of the Vite/Rolldown/Rollup plugin hook context (`this`) used by this plugin.
|
|
17
|
+
*/
|
|
18
|
+
type PluginContext = {
|
|
19
|
+
/** Log an informational message through Vite/Rolldown/Rollup's logging pipeline. */info: (message: string) => void; /** Log a warning through Vite/Rolldown/Rollup's logging pipeline without stopping the build. */
|
|
20
|
+
warn: (message: string) => void;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Minimum plugin interface compatible with Vite/Rolldown/Rollup.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* {
|
|
27
|
+
* name: 'rollupStats',
|
|
28
|
+
* async generateBundle(outputOptions, bundle) { ... },
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
type Plugin = {
|
|
32
|
+
/** Unique identifier for the plugin, used in error messages and logs. */name: string;
|
|
33
|
+
/**
|
|
34
|
+
* Hook called after the bundle has been fully generated but before it is
|
|
35
|
+
* written to disk. Receives the resolved output options and the complete
|
|
36
|
+
* output bundle map.
|
|
37
|
+
*/
|
|
38
|
+
generateBundle?: (this: PluginContext, outputOptions: OutputOptions, bundle: OutputBundle, isWrite: boolean) => void | Promise<void>;
|
|
39
|
+
};
|
|
7
40
|
type WebpackStatsOptions = {
|
|
8
41
|
/**
|
|
9
42
|
* JSON file output fileName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../../src/plugin.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../../src/plugin.ts"],"mappings":";;;;;;;;AAaA;;KAAY,aAAA;EAEV,gDAAA,GAAA,uBAoBG;EAjBH,MAAA;AAAA;;;;KAiBG,aAAA;EAKI,oFAHP,IAAA,GAAO,OAAA,mBAGe;EAAtB,IAAA,GAAO,OAAA;AAAA;;;;;;;;;;KAYG,MAAA;EAUR,yEARF,IAAA;EASE;;;;;EAFF,cAAA,IACE,IAAA,EAAM,aAAA,EACN,aAAA,EAAe,aAAA,EACf,MAAA,EAAQ,YAAA,EACR,OAAA,qBACU,OAAA;AAAA;AAAA,KAGT,mBAAA;EAAmB;;;;EAKtB,QAAA;EAOA;;;;EAFA,KAAA,GAAQ,UAAA;AAAA,IACN,IAAA,CAAK,YAAA,sBACP,sBAAA;AAAA,KAEG,4BAAA,GACD,mBAAA,KACE,aAAA,EAAe,aAAA,KAAkB,mBAAA;AAAA,cAE1B,YAAA,GACX,OAAA,GAAS,4BAAA,KACR,MAAA"}
|
package/dist/src/plugin.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.mjs","names":[],"sources":["../../src/plugin.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"plugin.mjs","names":[],"sources":["../../src/plugin.ts"],"sourcesContent":["import type { OutputBundle } from 'rollup-plugin-stats';\nimport extractStats, { type StatsOptions } from 'rollup-plugin-stats/extract';\n\nimport { type BundleTransformOptions, bundleToWebpackStats } from './transform';\nimport { type StatsWrite, statsWrite } from './write';\nimport { formatFileSize, getByteSize, resolveFilepath } from './utils';\n\nconst PLUGIN_NAME = 'webpackStats';\n\n/**\n * A subset of resolved output options provided to the `generateBundle` hook by Vite/Rolldown/Rollup,\n * containing only the fields this plugin uses to generate a stats file for a specific output.\n */\nexport type OutputOptions = {\n /** Output directory for the generated files. */\n dir?: string | undefined;\n\n /** Output format */\n format?:\n | 'es'\n | 'esm'\n | 'module'\n | 'cjs'\n | 'commonjs'\n | 'iife'\n | 'umd'\n | 'amd'\n | 'system'\n | 'systemjs'\n | undefined;\n};\n\n/**\n * Subset of the Vite/Rolldown/Rollup plugin hook context (`this`) used by this plugin.\n */\ntype PluginContext = {\n /** Log an informational message through Vite/Rolldown/Rollup's logging pipeline. */\n info: (message: string) => void;\n\n /** Log a warning through Vite/Rolldown/Rollup's logging pipeline without stopping the build. */\n warn: (message: string) => void;\n};\n\n/**\n * Minimum plugin interface compatible with Vite/Rolldown/Rollup.\n *\n * @example\n * {\n * name: 'rollupStats',\n * async generateBundle(outputOptions, bundle) { ... },\n * }\n */\nexport type Plugin = {\n /** Unique identifier for the plugin, used in error messages and logs. */\n name: string;\n\n /**\n * Hook called after the bundle has been fully generated but before it is\n * written to disk. Receives the resolved output options and the complete\n * output bundle map.\n */\n generateBundle?: (\n this: PluginContext,\n outputOptions: OutputOptions,\n bundle: OutputBundle,\n isWrite: boolean\n ) => void | Promise<void>;\n};\n\ntype WebpackStatsOptions = {\n /**\n * JSON file output fileName\n * default: webpack-stats.json\n */\n fileName?: string;\n /**\n * Custom file writer\n * @default - fs.write(FILENAME, JSON.stringify(STATS, null, 2));\n */\n write?: StatsWrite;\n} & Omit<StatsOptions, 'source' | 'map'> &\n BundleTransformOptions;\n\ntype WebpackStatsOptionsOrBuilder =\n | WebpackStatsOptions\n | ((outputOptions: OutputOptions) => WebpackStatsOptions);\n\nexport const webpackStats = (\n options: WebpackStatsOptionsOrBuilder = {}\n): Plugin => ({\n name: PLUGIN_NAME,\n async generateBundle(outputOptions, bundle) {\n const resolvedOptions =\n typeof options === 'function' ? options(outputOptions) : options;\n const {\n fileName,\n excludeAssets,\n excludeModules,\n write = statsWrite,\n ...transformOptions\n } = resolvedOptions;\n\n const rollupStats = extractStats(bundle, {\n excludeAssets,\n excludeModules,\n // Extract stats source to compute size\n source: true,\n });\n const stats = bundleToWebpackStats(rollupStats, transformOptions);\n const filepath = resolveFilepath(fileName, outputOptions.dir);\n\n try {\n const res = await write(\n filepath,\n stats as unknown as Record<string, unknown>\n );\n const outputSize = getByteSize(res.content);\n\n this.info(\n `Stats saved to ${res.filepath} (${formatFileSize(outputSize)})`\n );\n } catch (error: unknown) {\n const message =\n error instanceof Error ? error.message : JSON.stringify(error);\n\n // Log error, but do not throw to allow the compilation to continue\n this.warn(message);\n }\n },\n});\n"],"mappings":";;;;;;AAOA,MAAM,cAAc;AAgFpB,MAAa,gBACX,UAAwC,EAAE,MAC9B;CACZ,MAAM;CACN,MAAM,eAAe,eAAe,QAAQ;EAG1C,MAAM,EACJ,UACA,eACA,gBACA,QAAQ,YACR,GAAG,qBANH,OAAO,YAAY,aAAa,QAAQ,cAAc,GAAG;EAe3D,MAAM,QAAQ,qBANM,aAAa,QAAQ;GACvC;GACA;GAEA,QAAQ;GACT,CAAC,EAC8C,iBAAiB;EACjE,MAAM,WAAW,gBAAgB,UAAU,cAAc,IAAI;AAE7D,MAAI;GACF,MAAM,MAAM,MAAM,MAChB,UACA,MACD;GACD,MAAM,aAAa,YAAY,IAAI,QAAQ;AAE3C,QAAK,KACH,kBAAkB,IAAI,SAAS,IAAI,eAAe,WAAW,CAAC,GAC/D;WACM,OAAgB;GACvB,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU,KAAK,UAAU,MAAM;AAGhE,QAAK,KAAK,QAAQ;;;CAGvB"}
|
package/dist/transform.cjs
CHANGED
|
@@ -8,7 +8,14 @@ path = require_runtime.__toESM(path);
|
|
|
8
8
|
/**
|
|
9
9
|
* Recursivily check if a chunk is async based on the chunks issuers
|
|
10
10
|
*/
|
|
11
|
-
const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
|
|
11
|
+
const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = [], cache = /* @__PURE__ */ new Map()) => {
|
|
12
|
+
const cached = cache.get(chunk.fileName);
|
|
13
|
+
if (cached !== void 0) return cached;
|
|
14
|
+
const result = lookupChunkAsyncUncached(chunksIssuers, chunk, processedChunks, cache);
|
|
15
|
+
cache.set(chunk.fileName, result);
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
18
|
+
const lookupChunkAsyncUncached = (chunksIssuers, chunk, processedChunks, cache) => {
|
|
12
19
|
if (processedChunks.includes(chunk.fileName)) return true;
|
|
13
20
|
if (chunk.isEntry) return false;
|
|
14
21
|
if (chunk.isDynamicEntry) return true;
|
|
@@ -29,9 +36,8 @@ const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
|
|
|
29
36
|
* - if at least one issuer is sync, the chunk is sync
|
|
30
37
|
* - if none of the issuers are sync, the chunk is async
|
|
31
38
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return isAsync;
|
|
39
|
+
const nextProcessed = [...processedChunks, chunk.fileName];
|
|
40
|
+
return syncChunksIssuers.every((issuer) => lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache));
|
|
35
41
|
};
|
|
36
42
|
/**
|
|
37
43
|
* Store transformed sources
|
package/dist/transform.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.cjs","names":["getByteSize","getChunkId"],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = []\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n let isAsync = true;\n\n for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {\n isAsync = lookupChunkAsync(chunksIssuers, syncChunksIssuers[i], [\n ...processedChunks,\n chunk.fileName,\n ]);\n }\n\n return isAsync;\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transform.cjs","names":["getByteSize","getChunkId"],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = [],\n cache: Map<string, boolean> = new Map()\n): boolean => {\n const cached = cache.get(chunk.fileName);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = lookupChunkAsyncUncached(\n chunksIssuers,\n chunk,\n processedChunks,\n cache\n );\n\n cache.set(chunk.fileName, result);\n return result;\n};\n\nconst lookupChunkAsyncUncached = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string>,\n cache: Map<string, boolean>\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n const nextProcessed = [...processedChunks, chunk.fileName];\n\n return syncChunksIssuers.every((issuer) =>\n lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache)\n );\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
|
package/dist/transform.d.cts
CHANGED
|
@@ -35,7 +35,7 @@ type ChunksIssuers = Record<string, Array<ChunkStats>>;
|
|
|
35
35
|
/**
|
|
36
36
|
* Recursivily check if a chunk is async based on the chunks issuers
|
|
37
37
|
*/
|
|
38
|
-
declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>) => boolean;
|
|
38
|
+
declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>, cache?: Map<string, boolean>) => boolean;
|
|
39
39
|
type AssetSource = ChunkStats | AssetStats;
|
|
40
40
|
type ChunkSource = ChunkStats;
|
|
41
41
|
type ModuleSource = {
|
package/dist/transform.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.cts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"transform.d.cts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA,UACjB,KAAA,GAAO,GAAA;AAAA,KAqEJ,WAAA,GAAc,UAAA,GAAa,UAAA;AAAA,KAC3B,WAAA,GAAc,UAAA;AAAA,KACd,YAAA;EAAiB,QAAA;AAAA,IAAqB,WAAA;;;;cAKrC,gBAAA;;EAKJ,OAAA,EAAS,MAAA;EAET,IAAA,CAAK,EAAA,UAAY,MAAA,EAAQ,WAAA,GAAc,WAAA,GAAc,YAAA;EAvGC;;AAGxD;EA2GE,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;;;;EAOjD,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;EA9GzC;;;EAqHR,WAAA,GAAe,MAAA,EAAQ,0BAAA,KAA6B,YAAA;AAAA;AAAA,KAK1C,iBAAA,IACV,KAAA,EAAO,oBAAA,EACP,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,KAAA,KACL,oBAAA;AAAA,KAIO,sBAAA;EAnIV;;;;EAwIA,kBAAA;EAvIc;;;EA2Id,SAAA,GAAY,iBAAA;AAAA;AAAA,cAGD,oBAAA,GACX,MAAA,EAAQ,KAAA,EACR,aAAA,GAAgB,sBAAA,KACf,oBAAA"}
|
package/dist/transform.d.mts
CHANGED
|
@@ -35,7 +35,7 @@ type ChunksIssuers = Record<string, Array<ChunkStats>>;
|
|
|
35
35
|
/**
|
|
36
36
|
* Recursivily check if a chunk is async based on the chunks issuers
|
|
37
37
|
*/
|
|
38
|
-
declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>) => boolean;
|
|
38
|
+
declare const lookupChunkAsync: (chunksIssuers: ChunksIssuers, chunk: ChunkStats, processedChunks?: Array<string>, cache?: Map<string, boolean>) => boolean;
|
|
39
39
|
type AssetSource = ChunkStats | AssetStats;
|
|
40
40
|
type ChunkSource = ChunkStats;
|
|
41
41
|
type ModuleSource = {
|
package/dist/transform.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.mts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"transform.d.mts","names":[],"sources":["../src/transform.ts"],"mappings":";;;KAWY,yBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,yBAAA;EACf,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,GAAQ,KAAA;EACR,KAAA,GAAQ,KAAA;AAAA;AAAA,UAGO,0BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA;AAAA;AAAA,UAGO,sCAAA;EACf,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,0BAAA;EACtD,OAAA,GAAU,KAAA,CAAM,sCAAA;AAAA;AAAA,UAGD,oBAAA;EACf,OAAA;EACA,IAAA;EACA,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,MAAA,EAAQ,KAAA,CAAM,yBAAA;EACd,OAAA,EAAS,KAAA,CAAM,8BAAA;AAAA;AAAA,KAGL,aAAA,GAAgB,MAAA,SAAe,KAAA,CAAM,UAAA;;;;cAKpC,gBAAA,GACX,aAAA,EAAe,aAAA,EACf,KAAA,EAAO,UAAA,EACP,eAAA,GAAiB,KAAA,UACjB,KAAA,GAAO,GAAA;AAAA,KAqEJ,WAAA,GAAc,UAAA,GAAa,UAAA;AAAA,KAC3B,WAAA,GAAc,UAAA;AAAA,KACd,YAAA;EAAiB,QAAA;AAAA,IAAqB,WAAA;;;;cAKrC,gBAAA;;EAKJ,OAAA,EAAS,MAAA;EAET,IAAA,CAAK,EAAA,UAAY,MAAA,EAAQ,WAAA,GAAc,WAAA,GAAc,YAAA;EAvGC;;AAGxD;EA2GE,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;;;;EAOjD,UAAA,GAAc,KAAA,EAAO,yBAAA,KAA4B,WAAA;EA9GzC;;;EAqHR,WAAA,GAAe,MAAA,EAAQ,0BAAA,KAA6B,YAAA;AAAA;AAAA,KAK1C,iBAAA,IACV,KAAA,EAAO,oBAAA,EACP,OAAA,EAAS,gBAAA,EACT,MAAA,EAAQ,KAAA,KACL,oBAAA;AAAA,KAIO,sBAAA;EAnIV;;;;EAwIA,kBAAA;EAvIc;;;EA2Id,SAAA,GAAY,iBAAA;AAAA;AAAA,cAGD,oBAAA,GACX,MAAA,EAAQ,KAAA,EACR,aAAA,GAAgB,sBAAA,KACf,oBAAA"}
|
package/dist/transform.mjs
CHANGED
|
@@ -5,7 +5,14 @@ import path from "path";
|
|
|
5
5
|
/**
|
|
6
6
|
* Recursivily check if a chunk is async based on the chunks issuers
|
|
7
7
|
*/
|
|
8
|
-
const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
|
|
8
|
+
const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = [], cache = /* @__PURE__ */ new Map()) => {
|
|
9
|
+
const cached = cache.get(chunk.fileName);
|
|
10
|
+
if (cached !== void 0) return cached;
|
|
11
|
+
const result = lookupChunkAsyncUncached(chunksIssuers, chunk, processedChunks, cache);
|
|
12
|
+
cache.set(chunk.fileName, result);
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
const lookupChunkAsyncUncached = (chunksIssuers, chunk, processedChunks, cache) => {
|
|
9
16
|
if (processedChunks.includes(chunk.fileName)) return true;
|
|
10
17
|
if (chunk.isEntry) return false;
|
|
11
18
|
if (chunk.isDynamicEntry) return true;
|
|
@@ -26,9 +33,8 @@ const lookupChunkAsync = (chunksIssuers, chunk, processedChunks = []) => {
|
|
|
26
33
|
* - if at least one issuer is sync, the chunk is sync
|
|
27
34
|
* - if none of the issuers are sync, the chunk is async
|
|
28
35
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return isAsync;
|
|
36
|
+
const nextProcessed = [...processedChunks, chunk.fileName];
|
|
37
|
+
return syncChunksIssuers.every((issuer) => lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache));
|
|
32
38
|
};
|
|
33
39
|
/**
|
|
34
40
|
* Store transformed sources
|
package/dist/transform.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.mjs","names":[],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = []\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n let isAsync = true;\n\n for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {\n isAsync = lookupChunkAsync(chunksIssuers, syncChunksIssuers[i], [\n ...processedChunks,\n chunk.fileName,\n ]);\n }\n\n return isAsync;\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transform.mjs","names":[],"sources":["../src/transform.ts"],"sourcesContent":["import path from 'path';\nimport type {\n Stats,\n AssetStats,\n ChunkStats,\n ModuleStats,\n} from 'rollup-plugin-stats/extract';\n\nimport { getByteSize, getChunkId } from './utils';\n\n// https://github.com/relative-ci/bundle-stats/blob/master/packages/plugin-webpack-filter/src/index.ts\nexport type WebpackStatsFilteredAsset = {\n name: string;\n size?: number;\n};\n\nexport interface WebpackStatsFilteredChunk {\n id: number | string;\n entry: boolean;\n initial: boolean;\n files?: Array<string>;\n names?: Array<string>;\n}\n\nexport interface WebpackStatsFilteredModule {\n name: string;\n size?: number;\n chunks: Array<string | number>;\n}\n\nexport interface WebpackStatsFilteredConcatenatedModule {\n name: string;\n size?: number;\n}\n\nexport interface WebpackStatsFilteredRootModule extends WebpackStatsFilteredModule {\n modules?: Array<WebpackStatsFilteredConcatenatedModule>;\n}\n\nexport interface WebpackStatsFiltered {\n builtAt: number;\n hash?: string;\n assets: Array<WebpackStatsFilteredAsset>;\n chunks: Array<WebpackStatsFilteredChunk>;\n modules: Array<WebpackStatsFilteredRootModule>;\n}\n\nexport type ChunksIssuers = Record<string, Array<ChunkStats>>;\n\n/**\n * Recursivily check if a chunk is async based on the chunks issuers\n */\nexport const lookupChunkAsync = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string> = [],\n cache: Map<string, boolean> = new Map()\n): boolean => {\n const cached = cache.get(chunk.fileName);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = lookupChunkAsyncUncached(\n chunksIssuers,\n chunk,\n processedChunks,\n cache\n );\n\n cache.set(chunk.fileName, result);\n return result;\n};\n\nconst lookupChunkAsyncUncached = (\n chunksIssuers: ChunksIssuers,\n chunk: ChunkStats,\n processedChunks: Array<string>,\n cache: Map<string, boolean>\n): boolean => {\n // When the chunks are having a circular dependency, return true to continue the recursive check\n if (processedChunks.includes(chunk.fileName)) {\n return true;\n }\n\n if (chunk.isEntry) {\n return false;\n }\n\n if (chunk.isDynamicEntry) {\n return true;\n }\n\n const chunkIssuers = chunksIssuers[chunk.fileName];\n\n /**\n * A sync chunk without issuer chunks, is sync\n */\n if (!chunkIssuers) {\n return false;\n }\n\n const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {\n return chunkIssuer.isDynamicEntry === false;\n });\n\n /**\n * A sync chunk with all the chunk issuer async, is async\n */\n if (syncChunksIssuers.length === 0) {\n return true;\n }\n\n /**\n * Recursively lookup for sync loads on the 2nd level issuers\n * - if at least one issuer is sync, the chunk is sync\n * - if none of the issuers are sync, the chunk is async\n */\n const nextProcessed = [...processedChunks, chunk.fileName];\n\n return syncChunksIssuers.every((issuer) =>\n lookupChunkAsync(chunksIssuers, issuer, nextProcessed, cache)\n );\n};\n\ntype AssetSource = ChunkStats | AssetStats;\ntype ChunkSource = ChunkStats;\ntype ModuleSource = { fileName: string } & ModuleStats;\n\n/**\n * Store transformed sources\n */\nclass TransformSources {\n constructor() {\n this.entries = {};\n }\n\n entries: Record<string, unknown> = {};\n\n push(id: string, source: AssetSource | ChunkSource | ModuleSource) {\n this.entries[id] = source;\n }\n\n /**\n * Get asset source\n */\n getByAsset = (asset: WebpackStatsFilteredAsset): AssetSource => {\n return this.entries[asset.name] as AssetSource;\n };\n\n /**\n * Get chunk source\n */\n getByChunk = (chunk: WebpackStatsFilteredChunk): ChunkSource => {\n return this.entries[chunk.id] as ChunkSource;\n };\n\n /**\n * Get module source\n */\n getByModule = (module: WebpackStatsFilteredModule): ModuleSource => {\n return this.entries[module.name] as ModuleSource;\n };\n}\n\nexport type TransformCallback = (\n stats: WebpackStatsFiltered,\n sources: TransformSources,\n bundle: Stats\n) => WebpackStatsFiltered;\n\nconst defaultTransform: TransformCallback = (stats) => stats;\n\nexport type BundleTransformOptions = {\n /**\n * Extract module original size or rendered size\n * default: false\n */\n moduleOriginalSize?: boolean;\n /**\n * Callback function to access and mutate the resulting stats after the transformation\n */\n transform?: TransformCallback;\n};\n\nexport const bundleToWebpackStats = (\n bundle: Stats,\n pluginOptions?: BundleTransformOptions\n): WebpackStatsFiltered => {\n const options = {\n moduleOriginalSize: false,\n ...pluginOptions,\n } satisfies BundleTransformOptions;\n const { moduleOriginalSize, transform = defaultTransform } = options;\n\n const assets: Array<WebpackStatsFilteredAsset> = [];\n const chunks: Array<WebpackStatsFilteredChunk> = [];\n const moduleByFileName: Record<string, WebpackStatsFilteredModule> = {};\n const sources = new TransformSources();\n const chunksIssuers: ChunksIssuers = {};\n\n const entries = Object.values(bundle);\n\n // Collect metadata\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n entry.imports?.forEach((chunkImportFileName) => {\n // Skip circular references\n if (\n chunksIssuers[entry.fileName]?.find(\n (chunkIssuer) => chunkIssuer.fileName === chunkImportFileName\n )\n ) {\n return;\n }\n\n if (!chunksIssuers[chunkImportFileName]) {\n chunksIssuers[chunkImportFileName] = [];\n }\n\n chunksIssuers[chunkImportFileName].push(entry);\n });\n }\n });\n\n // Process data\n entries.forEach((entry) => {\n if (entry.type === 'chunk') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.code),\n });\n sources.push(entry.fileName, entry);\n\n const chunkId = getChunkId(entry);\n const chunkAsync = lookupChunkAsync(chunksIssuers, entry);\n\n chunks.push({\n id: chunkId,\n entry: entry.isEntry,\n initial: !chunkAsync,\n files: [entry.fileName],\n names: [entry.name],\n });\n sources.push(chunkId, entry);\n\n Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {\n // Remove unexpected rollup null prefix\n const normalizedModulePath = modulePath.replace('\\u0000', '');\n\n const relativeModulePath = path.relative(\n process.cwd(),\n normalizedModulePath\n );\n\n // Match webpack output - add current directory prefix for child modules\n const relativeModulePathWithPrefix = relativeModulePath.match(/^\\.\\./)\n ? relativeModulePath\n : `.${path.sep}${relativeModulePath}`;\n\n const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];\n\n if (moduleEntry) {\n moduleEntry.chunks.push(chunkId);\n } else {\n moduleByFileName[relativeModulePathWithPrefix] = {\n name: relativeModulePathWithPrefix,\n size: moduleOriginalSize\n ? moduleInfo.originalLength\n : moduleInfo.renderedLength,\n chunks: [chunkId],\n };\n sources.push(relativeModulePathWithPrefix, {\n fileName: modulePath,\n ...moduleInfo,\n });\n }\n });\n } else if (entry.type === 'asset') {\n assets.push({\n name: entry.fileName,\n size: getByteSize(entry.source),\n });\n sources.push(entry.fileName, entry);\n } else {\n // noop for unknown types\n }\n });\n\n const stats: WebpackStatsFiltered = {\n builtAt: Date.now(),\n assets,\n chunks,\n modules: Object.values(moduleByFileName),\n };\n\n let result: WebpackStatsFiltered;\n\n try {\n result = transform(stats, sources, bundle);\n } catch (error) {\n console.error(\n 'Custom transform failed! Returning stats without any transforms.',\n error\n );\n result = stats;\n }\n\n return result;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rollup-plugin-webpack-stats",
|
|
3
3
|
"description": "Rollup/Vite/Rolldown plugin to generate a stats JSON file with a bundle-stats webpack-compatible structure",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.1-beta.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -84,16 +84,14 @@
|
|
|
84
84
|
"prettier": "3.8.1",
|
|
85
85
|
"release-it": "19.2.4",
|
|
86
86
|
"rimraf": "6.1.3",
|
|
87
|
-
"rollup": "4.59.0",
|
|
88
87
|
"tsdown": "0.21.2",
|
|
89
88
|
"tslib": "2.8.1",
|
|
90
89
|
"typescript": "5.9.3",
|
|
91
90
|
"typescript-eslint": "8.57.0",
|
|
92
|
-
"vite": "7.3.1",
|
|
93
91
|
"vitest": "4.1.0"
|
|
94
92
|
},
|
|
95
93
|
"dependencies": {
|
|
96
|
-
"rollup-plugin-stats": "2.1.
|
|
94
|
+
"rollup-plugin-stats": "2.1.1-beta.3"
|
|
97
95
|
},
|
|
98
96
|
"peerDependencies": {
|
|
99
97
|
"rolldown": "^1.0.0-beta.0",
|
package/dist/src/types.d.cts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { OutputOptions, Plugin } from "rollup";
|
|
2
|
-
import { Plugin as Plugin$1 } from "vite";
|
|
3
|
-
|
|
4
|
-
//#region src/types.d.ts
|
|
5
|
-
type Plugin$2 = Plugin$1 & Plugin;
|
|
6
|
-
type OutputOptions$1 = OutputOptions;
|
|
7
|
-
//#endregion
|
|
8
|
-
export { OutputOptions$1 as OutputOptions, Plugin$2 as Plugin };
|
|
9
|
-
//# sourceMappingURL=types.d.cts.map
|
package/dist/src/types.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/types.ts"],"mappings":";;;;KAMY,QAAA,GAAS,QAAA,GAAa,MAAA;AAAA,KACtB,eAAA,GAAgB,aAAA"}
|
package/dist/src/types.d.mts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { OutputOptions, Plugin } from "rollup";
|
|
2
|
-
import { Plugin as Plugin$1 } from "vite";
|
|
3
|
-
|
|
4
|
-
//#region src/types.d.ts
|
|
5
|
-
type Plugin$2 = Plugin$1 & Plugin;
|
|
6
|
-
type OutputOptions$1 = OutputOptions;
|
|
7
|
-
//#endregion
|
|
8
|
-
export { OutputOptions$1 as OutputOptions, Plugin$2 as Plugin };
|
|
9
|
-
//# sourceMappingURL=types.d.mts.map
|
package/dist/src/types.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/types.ts"],"mappings":";;;;KAMY,QAAA,GAAS,QAAA,GAAa,MAAA;AAAA,KACtB,eAAA,GAAgB,aAAA"}
|