rollup-plugin-webpack-stats 1.2.4-beta.6 → 2.0.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 +6 -3
- package/dist/chunks/transform.cjs +237 -0
- package/dist/chunks/transform.cjs.map +1 -0
- package/dist/chunks/transform.mjs +232 -0
- package/dist/chunks/transform.mjs.map +1 -0
- package/dist/index.cjs +32 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +32 -11
- package/dist/index.mjs.map +1 -1
- package/dist/plugin.d.ts +9 -2
- package/dist/transform.cjs +6 -219
- package/dist/transform.cjs.map +1 -1
- package/dist/transform.d.ts +0 -9
- package/dist/transform.mjs +4 -221
- package/dist/transform.mjs.map +1 -1
- package/dist/utils.d.ts +3 -4
- package/dist/write.d.ts +6 -0
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -55,10 +55,13 @@ export default defineConfig((env) => ({
|
|
|
55
55
|
|
|
56
56
|
### Options
|
|
57
57
|
|
|
58
|
-
- `fileName` - JSON
|
|
59
|
-
- `excludeAssets` - exclude matching assets: `string | RegExp | ((filepath: string) => boolean) | Array<string | RegExp | ((filepath: string) => boolean)>`
|
|
60
|
-
- `excludeModules` - exclude matching modules: `string | RegExp | ((filepath: string) => boolean) | Array<string | RegExp | ((filepath: string) => boolean)>`
|
|
58
|
+
- `fileName` - the JSON filepath relative to the build folder or absolute(default: `webpack-stats.json`)
|
|
61
59
|
- `transform` - access and mutate the resulting stats after the conversion: `(stats: WebpackStatsFilterd, sources: TransformSources, bundle: OutputBundle) => WebpackStatsFilterd`
|
|
60
|
+
- `moduleOriginalSize` - extract module original size or rendered size (default: `false`)
|
|
61
|
+
- `write` - format and write the stats to disk(default: `fs.write(filename, JSON.stringify(stats, null, 2))`)
|
|
62
|
+
- rollup stats options ([rollup-plugin-stats](https://github.com/relative-ci/rollup-plugin-stats#options))
|
|
63
|
+
- `excludeAssets` - exclude matching assets: `string | RegExp | ((filepath: string) => boolean) | Array<string | RegExp | ((filepath: string) => boolean)>`
|
|
64
|
+
- `excludeModules` - exclude matching modules: `string | RegExp | ((filepath: string) => boolean) | Array<string | RegExp | ((filepath: string) => boolean)>`
|
|
62
65
|
|
|
63
66
|
### Examples
|
|
64
67
|
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path$1 = require('path');
|
|
4
|
+
var path = require('node:path');
|
|
5
|
+
var crypto = require('node:crypto');
|
|
6
|
+
|
|
7
|
+
const HASH_LENGTH = 7;
|
|
8
|
+
/**
|
|
9
|
+
* Get content byte size
|
|
10
|
+
*/
|
|
11
|
+
function getByteSize(content) {
|
|
12
|
+
if (typeof content === 'string') {
|
|
13
|
+
return Buffer.from(content).length;
|
|
14
|
+
}
|
|
15
|
+
return content?.length || 0;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generate a 7 chars hash from a filepath
|
|
19
|
+
*/
|
|
20
|
+
function getHash(filepath) {
|
|
21
|
+
const digest = crypto.createHash('sha256');
|
|
22
|
+
return digest.update(Buffer.from(filepath)).digest('hex').substr(0, HASH_LENGTH);
|
|
23
|
+
}
|
|
24
|
+
function getChunkId(chunk) {
|
|
25
|
+
let value = chunk.name;
|
|
26
|
+
// Use entry module relative path
|
|
27
|
+
if (chunk.moduleIds?.length > 0) {
|
|
28
|
+
const absoluteModulePath = chunk.moduleIds[chunk.moduleIds.length - 1];
|
|
29
|
+
value = path.relative(process.cwd(), absoluteModulePath);
|
|
30
|
+
}
|
|
31
|
+
return getHash([chunk, value].join('-'));
|
|
32
|
+
}
|
|
33
|
+
function round(value, precision = 2) {
|
|
34
|
+
const multiplier = 10 ^ precision;
|
|
35
|
+
return Math.round(value * multiplier) / multiplier;
|
|
36
|
+
}
|
|
37
|
+
const FILE_SIZE = {
|
|
38
|
+
BYTE: {
|
|
39
|
+
symbol: 'B',
|
|
40
|
+
multiplier: 1,
|
|
41
|
+
},
|
|
42
|
+
KILO: {
|
|
43
|
+
symbol: 'KiB',
|
|
44
|
+
multiplier: 1024,
|
|
45
|
+
},
|
|
46
|
+
MEGA: {
|
|
47
|
+
symbol: 'MiB',
|
|
48
|
+
multiplier: 1024 * 1024,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
function formatFileSize(value) {
|
|
52
|
+
let unit = FILE_SIZE.BYTE;
|
|
53
|
+
if (typeof value !== 'number') {
|
|
54
|
+
return `0${unit.symbol}`;
|
|
55
|
+
}
|
|
56
|
+
if (value < FILE_SIZE.KILO.multiplier) {
|
|
57
|
+
unit = FILE_SIZE.BYTE;
|
|
58
|
+
}
|
|
59
|
+
else if (value < FILE_SIZE.MEGA.multiplier) {
|
|
60
|
+
unit = FILE_SIZE.KILO;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
unit = FILE_SIZE.MEGA;
|
|
64
|
+
}
|
|
65
|
+
return `${round(value / unit.multiplier, 2)}${unit.symbol}`;
|
|
66
|
+
}
|
|
67
|
+
const DEFAULT_FILE_NAME = 'webpack-stats.json';
|
|
68
|
+
function resolveFilepath(fileName = DEFAULT_FILE_NAME, outputDir) {
|
|
69
|
+
// Check if the fileName is an absolute path
|
|
70
|
+
if (path.isAbsolute(fileName)) {
|
|
71
|
+
return fileName;
|
|
72
|
+
}
|
|
73
|
+
// If the fileName is not an absolute path, join it with the output directory or the current working directory
|
|
74
|
+
return path.join(outputDir || process.cwd(), fileName);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Recursivily check if a chunk is async based on the chunks issuers
|
|
79
|
+
*/
|
|
80
|
+
const lookupChunkAsync = (chunk, chunksIssuers) => {
|
|
81
|
+
if (chunk.isDynamicEntry) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
if (chunk.isEntry) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const chunkIssuers = chunksIssuers[chunk.fileName];
|
|
88
|
+
/**
|
|
89
|
+
* A sync chunk without issuer chunks, is sync
|
|
90
|
+
*/
|
|
91
|
+
if (!chunkIssuers) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {
|
|
95
|
+
return chunkIssuer.isDynamicEntry === false;
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* A sync chunk with all the chunk issuer async, is async
|
|
99
|
+
*/
|
|
100
|
+
if (syncChunksIssuers.length === 0) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Recursively lookup for sync loads on the 2nd level issuers
|
|
105
|
+
* - if at least one issuer is sync, the chunk is sync
|
|
106
|
+
* - if none of the issuers are sync, the chunk is async
|
|
107
|
+
*/
|
|
108
|
+
let isAsync = true;
|
|
109
|
+
for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {
|
|
110
|
+
isAsync = lookupChunkAsync(syncChunksIssuers[i], chunksIssuers);
|
|
111
|
+
}
|
|
112
|
+
return isAsync;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Store transformed sources
|
|
116
|
+
*/
|
|
117
|
+
class TransformSources {
|
|
118
|
+
constructor() {
|
|
119
|
+
this.entries = {};
|
|
120
|
+
}
|
|
121
|
+
entries = {};
|
|
122
|
+
push(id, source) {
|
|
123
|
+
this.entries[id] = source;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get asset source
|
|
127
|
+
*/
|
|
128
|
+
getByAsset = (asset) => {
|
|
129
|
+
return this.entries[asset.name];
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Get chunk source
|
|
133
|
+
*/
|
|
134
|
+
getByChunk = (chunk) => {
|
|
135
|
+
return this.entries[chunk.id];
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Get module source
|
|
139
|
+
*/
|
|
140
|
+
getByModule = (module) => {
|
|
141
|
+
return this.entries[module.name];
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const defaultTransform = (stats) => stats;
|
|
145
|
+
const bundleToWebpackStats = (bundle, pluginOptions) => {
|
|
146
|
+
const options = { moduleOriginalSize: false, ...pluginOptions };
|
|
147
|
+
const { moduleOriginalSize, transform = defaultTransform } = options;
|
|
148
|
+
const assets = [];
|
|
149
|
+
const chunks = [];
|
|
150
|
+
const moduleByFileName = {};
|
|
151
|
+
const sources = new TransformSources();
|
|
152
|
+
const chunksIssuers = {};
|
|
153
|
+
const entries = Object.values(bundle);
|
|
154
|
+
// Collect metadata
|
|
155
|
+
entries.forEach((entry) => {
|
|
156
|
+
if (entry.type === 'chunk') {
|
|
157
|
+
entry.imports?.forEach((chunkDependency) => {
|
|
158
|
+
if (!chunksIssuers[chunkDependency]) {
|
|
159
|
+
chunksIssuers[chunkDependency] = [];
|
|
160
|
+
}
|
|
161
|
+
chunksIssuers[chunkDependency].push(entry);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// Process data
|
|
166
|
+
entries.forEach((entry) => {
|
|
167
|
+
if (entry.type === 'chunk') {
|
|
168
|
+
assets.push({
|
|
169
|
+
name: entry.fileName,
|
|
170
|
+
size: getByteSize(entry.code),
|
|
171
|
+
});
|
|
172
|
+
sources.push(entry.fileName, entry);
|
|
173
|
+
const chunkId = getChunkId(entry);
|
|
174
|
+
const chunkAsync = lookupChunkAsync(entry, chunksIssuers);
|
|
175
|
+
chunks.push({
|
|
176
|
+
id: chunkId,
|
|
177
|
+
entry: entry.isEntry,
|
|
178
|
+
initial: !chunkAsync,
|
|
179
|
+
files: [entry.fileName],
|
|
180
|
+
names: [entry.name],
|
|
181
|
+
});
|
|
182
|
+
sources.push(chunkId, entry);
|
|
183
|
+
Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {
|
|
184
|
+
// Remove unexpected rollup null prefix
|
|
185
|
+
const normalizedModulePath = modulePath.replace('\u0000', '');
|
|
186
|
+
const relativeModulePath = path$1.relative(process.cwd(), normalizedModulePath);
|
|
187
|
+
// Match webpack output - add current directory prefix for child modules
|
|
188
|
+
const relativeModulePathWithPrefix = relativeModulePath.match(/^\.\./)
|
|
189
|
+
? relativeModulePath
|
|
190
|
+
: `.${path$1.sep}${relativeModulePath}`;
|
|
191
|
+
const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];
|
|
192
|
+
if (moduleEntry) {
|
|
193
|
+
moduleEntry.chunks.push(chunkId);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
moduleByFileName[relativeModulePathWithPrefix] = {
|
|
197
|
+
name: relativeModulePathWithPrefix,
|
|
198
|
+
size: moduleOriginalSize
|
|
199
|
+
? moduleInfo.originalLength
|
|
200
|
+
: moduleInfo.renderedLength,
|
|
201
|
+
chunks: [chunkId],
|
|
202
|
+
};
|
|
203
|
+
sources.push(relativeModulePathWithPrefix, { fileName: modulePath, ...moduleInfo });
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
else if (entry.type === 'asset') {
|
|
208
|
+
assets.push({
|
|
209
|
+
name: entry.fileName,
|
|
210
|
+
size: getByteSize(entry.source.toString()),
|
|
211
|
+
});
|
|
212
|
+
sources.push(entry.fileName, entry);
|
|
213
|
+
}
|
|
214
|
+
else ;
|
|
215
|
+
});
|
|
216
|
+
const stats = {
|
|
217
|
+
builtAt: Date.now(),
|
|
218
|
+
assets,
|
|
219
|
+
chunks,
|
|
220
|
+
modules: Object.values(moduleByFileName),
|
|
221
|
+
};
|
|
222
|
+
let result;
|
|
223
|
+
try {
|
|
224
|
+
result = transform(stats, sources, bundle);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
console.error('Custom transform failed! Returning stats without any transforms.', error);
|
|
228
|
+
result = stats;
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
exports.bundleToWebpackStats = bundleToWebpackStats;
|
|
234
|
+
exports.formatFileSize = formatFileSize;
|
|
235
|
+
exports.lookupChunkAsync = lookupChunkAsync;
|
|
236
|
+
exports.resolveFilepath = resolveFilepath;
|
|
237
|
+
//# sourceMappingURL=transform.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.cjs","sources":["../../src/utils.ts","../../src/transform.ts"],"sourcesContent":[null,null],"names":["path"],"mappings":"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"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import path$1 from 'path';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
|
|
5
|
+
const HASH_LENGTH = 7;
|
|
6
|
+
/**
|
|
7
|
+
* Get content byte size
|
|
8
|
+
*/
|
|
9
|
+
function getByteSize(content) {
|
|
10
|
+
if (typeof content === 'string') {
|
|
11
|
+
return Buffer.from(content).length;
|
|
12
|
+
}
|
|
13
|
+
return content?.length || 0;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generate a 7 chars hash from a filepath
|
|
17
|
+
*/
|
|
18
|
+
function getHash(filepath) {
|
|
19
|
+
const digest = crypto.createHash('sha256');
|
|
20
|
+
return digest.update(Buffer.from(filepath)).digest('hex').substr(0, HASH_LENGTH);
|
|
21
|
+
}
|
|
22
|
+
function getChunkId(chunk) {
|
|
23
|
+
let value = chunk.name;
|
|
24
|
+
// Use entry module relative path
|
|
25
|
+
if (chunk.moduleIds?.length > 0) {
|
|
26
|
+
const absoluteModulePath = chunk.moduleIds[chunk.moduleIds.length - 1];
|
|
27
|
+
value = path.relative(process.cwd(), absoluteModulePath);
|
|
28
|
+
}
|
|
29
|
+
return getHash([chunk, value].join('-'));
|
|
30
|
+
}
|
|
31
|
+
function round(value, precision = 2) {
|
|
32
|
+
const multiplier = 10 ^ precision;
|
|
33
|
+
return Math.round(value * multiplier) / multiplier;
|
|
34
|
+
}
|
|
35
|
+
const FILE_SIZE = {
|
|
36
|
+
BYTE: {
|
|
37
|
+
symbol: 'B',
|
|
38
|
+
multiplier: 1,
|
|
39
|
+
},
|
|
40
|
+
KILO: {
|
|
41
|
+
symbol: 'KiB',
|
|
42
|
+
multiplier: 1024,
|
|
43
|
+
},
|
|
44
|
+
MEGA: {
|
|
45
|
+
symbol: 'MiB',
|
|
46
|
+
multiplier: 1024 * 1024,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
function formatFileSize(value) {
|
|
50
|
+
let unit = FILE_SIZE.BYTE;
|
|
51
|
+
if (typeof value !== 'number') {
|
|
52
|
+
return `0${unit.symbol}`;
|
|
53
|
+
}
|
|
54
|
+
if (value < FILE_SIZE.KILO.multiplier) {
|
|
55
|
+
unit = FILE_SIZE.BYTE;
|
|
56
|
+
}
|
|
57
|
+
else if (value < FILE_SIZE.MEGA.multiplier) {
|
|
58
|
+
unit = FILE_SIZE.KILO;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
unit = FILE_SIZE.MEGA;
|
|
62
|
+
}
|
|
63
|
+
return `${round(value / unit.multiplier, 2)}${unit.symbol}`;
|
|
64
|
+
}
|
|
65
|
+
const DEFAULT_FILE_NAME = 'webpack-stats.json';
|
|
66
|
+
function resolveFilepath(fileName = DEFAULT_FILE_NAME, outputDir) {
|
|
67
|
+
// Check if the fileName is an absolute path
|
|
68
|
+
if (path.isAbsolute(fileName)) {
|
|
69
|
+
return fileName;
|
|
70
|
+
}
|
|
71
|
+
// If the fileName is not an absolute path, join it with the output directory or the current working directory
|
|
72
|
+
return path.join(outputDir || process.cwd(), fileName);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Recursivily check if a chunk is async based on the chunks issuers
|
|
77
|
+
*/
|
|
78
|
+
const lookupChunkAsync = (chunk, chunksIssuers) => {
|
|
79
|
+
if (chunk.isDynamicEntry) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (chunk.isEntry) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const chunkIssuers = chunksIssuers[chunk.fileName];
|
|
86
|
+
/**
|
|
87
|
+
* A sync chunk without issuer chunks, is sync
|
|
88
|
+
*/
|
|
89
|
+
if (!chunkIssuers) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {
|
|
93
|
+
return chunkIssuer.isDynamicEntry === false;
|
|
94
|
+
});
|
|
95
|
+
/**
|
|
96
|
+
* A sync chunk with all the chunk issuer async, is async
|
|
97
|
+
*/
|
|
98
|
+
if (syncChunksIssuers.length === 0) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Recursively lookup for sync loads on the 2nd level issuers
|
|
103
|
+
* - if at least one issuer is sync, the chunk is sync
|
|
104
|
+
* - if none of the issuers are sync, the chunk is async
|
|
105
|
+
*/
|
|
106
|
+
let isAsync = true;
|
|
107
|
+
for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {
|
|
108
|
+
isAsync = lookupChunkAsync(syncChunksIssuers[i], chunksIssuers);
|
|
109
|
+
}
|
|
110
|
+
return isAsync;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Store transformed sources
|
|
114
|
+
*/
|
|
115
|
+
class TransformSources {
|
|
116
|
+
constructor() {
|
|
117
|
+
this.entries = {};
|
|
118
|
+
}
|
|
119
|
+
entries = {};
|
|
120
|
+
push(id, source) {
|
|
121
|
+
this.entries[id] = source;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get asset source
|
|
125
|
+
*/
|
|
126
|
+
getByAsset = (asset) => {
|
|
127
|
+
return this.entries[asset.name];
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Get chunk source
|
|
131
|
+
*/
|
|
132
|
+
getByChunk = (chunk) => {
|
|
133
|
+
return this.entries[chunk.id];
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Get module source
|
|
137
|
+
*/
|
|
138
|
+
getByModule = (module) => {
|
|
139
|
+
return this.entries[module.name];
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const defaultTransform = (stats) => stats;
|
|
143
|
+
const bundleToWebpackStats = (bundle, pluginOptions) => {
|
|
144
|
+
const options = { moduleOriginalSize: false, ...pluginOptions };
|
|
145
|
+
const { moduleOriginalSize, transform = defaultTransform } = options;
|
|
146
|
+
const assets = [];
|
|
147
|
+
const chunks = [];
|
|
148
|
+
const moduleByFileName = {};
|
|
149
|
+
const sources = new TransformSources();
|
|
150
|
+
const chunksIssuers = {};
|
|
151
|
+
const entries = Object.values(bundle);
|
|
152
|
+
// Collect metadata
|
|
153
|
+
entries.forEach((entry) => {
|
|
154
|
+
if (entry.type === 'chunk') {
|
|
155
|
+
entry.imports?.forEach((chunkDependency) => {
|
|
156
|
+
if (!chunksIssuers[chunkDependency]) {
|
|
157
|
+
chunksIssuers[chunkDependency] = [];
|
|
158
|
+
}
|
|
159
|
+
chunksIssuers[chunkDependency].push(entry);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
// Process data
|
|
164
|
+
entries.forEach((entry) => {
|
|
165
|
+
if (entry.type === 'chunk') {
|
|
166
|
+
assets.push({
|
|
167
|
+
name: entry.fileName,
|
|
168
|
+
size: getByteSize(entry.code),
|
|
169
|
+
});
|
|
170
|
+
sources.push(entry.fileName, entry);
|
|
171
|
+
const chunkId = getChunkId(entry);
|
|
172
|
+
const chunkAsync = lookupChunkAsync(entry, chunksIssuers);
|
|
173
|
+
chunks.push({
|
|
174
|
+
id: chunkId,
|
|
175
|
+
entry: entry.isEntry,
|
|
176
|
+
initial: !chunkAsync,
|
|
177
|
+
files: [entry.fileName],
|
|
178
|
+
names: [entry.name],
|
|
179
|
+
});
|
|
180
|
+
sources.push(chunkId, entry);
|
|
181
|
+
Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {
|
|
182
|
+
// Remove unexpected rollup null prefix
|
|
183
|
+
const normalizedModulePath = modulePath.replace('\u0000', '');
|
|
184
|
+
const relativeModulePath = path$1.relative(process.cwd(), normalizedModulePath);
|
|
185
|
+
// Match webpack output - add current directory prefix for child modules
|
|
186
|
+
const relativeModulePathWithPrefix = relativeModulePath.match(/^\.\./)
|
|
187
|
+
? relativeModulePath
|
|
188
|
+
: `.${path$1.sep}${relativeModulePath}`;
|
|
189
|
+
const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];
|
|
190
|
+
if (moduleEntry) {
|
|
191
|
+
moduleEntry.chunks.push(chunkId);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
moduleByFileName[relativeModulePathWithPrefix] = {
|
|
195
|
+
name: relativeModulePathWithPrefix,
|
|
196
|
+
size: moduleOriginalSize
|
|
197
|
+
? moduleInfo.originalLength
|
|
198
|
+
: moduleInfo.renderedLength,
|
|
199
|
+
chunks: [chunkId],
|
|
200
|
+
};
|
|
201
|
+
sources.push(relativeModulePathWithPrefix, { fileName: modulePath, ...moduleInfo });
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else if (entry.type === 'asset') {
|
|
206
|
+
assets.push({
|
|
207
|
+
name: entry.fileName,
|
|
208
|
+
size: getByteSize(entry.source.toString()),
|
|
209
|
+
});
|
|
210
|
+
sources.push(entry.fileName, entry);
|
|
211
|
+
}
|
|
212
|
+
else ;
|
|
213
|
+
});
|
|
214
|
+
const stats = {
|
|
215
|
+
builtAt: Date.now(),
|
|
216
|
+
assets,
|
|
217
|
+
chunks,
|
|
218
|
+
modules: Object.values(moduleByFileName),
|
|
219
|
+
};
|
|
220
|
+
let result;
|
|
221
|
+
try {
|
|
222
|
+
result = transform(stats, sources, bundle);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
console.error('Custom transform failed! Returning stats without any transforms.', error);
|
|
226
|
+
result = stats;
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export { bundleToWebpackStats as b, formatFileSize as f, lookupChunkAsync as l, resolveFilepath as r };
|
|
232
|
+
//# sourceMappingURL=transform.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.mjs","sources":["../../src/utils.ts","../../src/transform.ts"],"sourcesContent":[null,null],"names":["path"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var extractStats = require('rollup-plugin-stats/extract');
|
|
4
|
+
var transform = require('./chunks/transform.cjs');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var fs = require('node:fs/promises');
|
|
4
7
|
require('path');
|
|
5
|
-
require('crypto');
|
|
8
|
+
require('node:crypto');
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
async function statsWrite(filepath, stats) {
|
|
11
|
+
const content = JSON.stringify(stats, null, 2);
|
|
12
|
+
// Create base directory if it does not exist
|
|
13
|
+
await fs.mkdir(path.dirname(filepath), { recursive: true });
|
|
14
|
+
await fs.writeFile(filepath, content);
|
|
15
|
+
return {
|
|
16
|
+
filepath,
|
|
17
|
+
content,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const PLUGIN_NAME = 'webpackStats';
|
|
8
22
|
const webpackStats = (options = {}) => ({
|
|
9
|
-
name:
|
|
10
|
-
generateBundle(outputOptions, bundle) {
|
|
23
|
+
name: PLUGIN_NAME,
|
|
24
|
+
async generateBundle(outputOptions, bundle) {
|
|
11
25
|
const resolvedOptions = typeof options === 'function' ? options(outputOptions) : options;
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
const { fileName, excludeAssets, excludeModules, write = statsWrite, ...transformOptions } = resolvedOptions;
|
|
27
|
+
const rollupStats = extractStats(bundle, { excludeAssets, excludeModules });
|
|
28
|
+
const stats = transform.bundleToWebpackStats(rollupStats, transformOptions);
|
|
29
|
+
const filepath = transform.resolveFilepath(fileName, outputOptions.dir);
|
|
30
|
+
try {
|
|
31
|
+
const res = await write(filepath, stats);
|
|
32
|
+
const outputSize = Buffer.byteLength(res.content, 'utf-8');
|
|
33
|
+
this.info(`Stats saved to ${res.filepath} (${transform.formatFileSize(outputSize)})`);
|
|
34
|
+
}
|
|
35
|
+
catch (error) { // eslint-disable-line
|
|
36
|
+
// Log error, but do not throw to allow the compilation to continue
|
|
37
|
+
this.warn(error);
|
|
38
|
+
}
|
|
18
39
|
},
|
|
19
40
|
});
|
|
20
41
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/plugin.ts"],"sourcesContent":[null],"names":["bundleToWebpackStats"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/write.ts","../src/plugin.ts"],"sourcesContent":[null,null],"names":["bundleToWebpackStats","resolveFilepath","formatFileSize"],"mappings":";;;;;;;;;AAaO,eAAe,UAAU,CAE9B,QAAgB,EAAE,KAAQ,EAAA;AAC1B,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;;ACnBA,MAAM,WAAW,GAAG,cAAc;AAmBrB,MAAA,YAAY,GAAG,CAC1B,UAAwC,EAAE,MAC9B;AACZ,IAAA,IAAI,EAAE,WAAW;AACjB,IAAA,MAAM,cAAc,CAAC,aAAa,EAAE,MAAM,EAAA;AACxC,QAAA,MAAM,eAAe,GAAG,OAAO,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO;AACxF,QAAA,MAAM,EACJ,QAAQ,EACR,aAAa,EACb,cAAc,EACd,KAAK,GAAG,UAAU,EAClB,GAAG,gBAAgB,EACpB,GAAG,eAAe;AAEnB,QAAA,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;QAC3E,MAAM,KAAK,GAAGA,8BAAoB,CAAC,WAAW,EAAE,gBAAgB,CAAC;QACjE,MAAM,QAAQ,GAAGC,yBAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC;AAE7D,QAAA,IAAI;YACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,KAA2C,CAAC;AAC9E,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;AAE1D,YAAA,IAAI,CAAC,IAAI,CAAC,CAAA,eAAA,EAAkB,GAAG,CAAC,QAAQ,CAAK,EAAA,EAAAC,wBAAc,CAAC,UAAU,CAAC,CAAA,CAAA,CAAG,CAAC;;AAC3E,QAAA,OAAO,KAAU,EAAE;;AAEnB,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;KAEnB;AACF,CAAA;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
|
-
import
|
|
1
|
+
import extractStats from 'rollup-plugin-stats/extract';
|
|
2
|
+
import { b as bundleToWebpackStats, r as resolveFilepath, f as formatFileSize } from './chunks/transform.mjs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
2
5
|
import 'path';
|
|
3
|
-
import 'crypto';
|
|
6
|
+
import 'node:crypto';
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
async function statsWrite(filepath, stats) {
|
|
9
|
+
const content = JSON.stringify(stats, null, 2);
|
|
10
|
+
// Create base directory if it does not exist
|
|
11
|
+
await fs.mkdir(path.dirname(filepath), { recursive: true });
|
|
12
|
+
await fs.writeFile(filepath, content);
|
|
13
|
+
return {
|
|
14
|
+
filepath,
|
|
15
|
+
content,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const PLUGIN_NAME = 'webpackStats';
|
|
6
20
|
const webpackStats = (options = {}) => ({
|
|
7
|
-
name:
|
|
8
|
-
generateBundle(outputOptions, bundle) {
|
|
21
|
+
name: PLUGIN_NAME,
|
|
22
|
+
async generateBundle(outputOptions, bundle) {
|
|
9
23
|
const resolvedOptions = typeof options === 'function' ? options(outputOptions) : options;
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
24
|
+
const { fileName, excludeAssets, excludeModules, write = statsWrite, ...transformOptions } = resolvedOptions;
|
|
25
|
+
const rollupStats = extractStats(bundle, { excludeAssets, excludeModules });
|
|
26
|
+
const stats = bundleToWebpackStats(rollupStats, transformOptions);
|
|
27
|
+
const filepath = resolveFilepath(fileName, outputOptions.dir);
|
|
28
|
+
try {
|
|
29
|
+
const res = await write(filepath, stats);
|
|
30
|
+
const outputSize = Buffer.byteLength(res.content, 'utf-8');
|
|
31
|
+
this.info(`Stats saved to ${res.filepath} (${formatFileSize(outputSize)})`);
|
|
32
|
+
}
|
|
33
|
+
catch (error) { // eslint-disable-line
|
|
34
|
+
// Log error, but do not throw to allow the compilation to continue
|
|
35
|
+
this.warn(error);
|
|
36
|
+
}
|
|
16
37
|
},
|
|
17
38
|
});
|
|
18
39
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/plugin.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/write.ts","../src/plugin.ts"],"sourcesContent":[null,null],"names":[],"mappings":";;;;;;;AAaO,eAAe,UAAU,CAE9B,QAAgB,EAAE,KAAQ,EAAA;AAC1B,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;;ACnBA,MAAM,WAAW,GAAG,cAAc;AAmBrB,MAAA,YAAY,GAAG,CAC1B,UAAwC,EAAE,MAC9B;AACZ,IAAA,IAAI,EAAE,WAAW;AACjB,IAAA,MAAM,cAAc,CAAC,aAAa,EAAE,MAAM,EAAA;AACxC,QAAA,MAAM,eAAe,GAAG,OAAO,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO;AACxF,QAAA,MAAM,EACJ,QAAQ,EACR,aAAa,EACb,cAAc,EACd,KAAK,GAAG,UAAU,EAClB,GAAG,gBAAgB,EACpB,GAAG,eAAe;AAEnB,QAAA,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;QAC3E,MAAM,KAAK,GAAG,oBAAoB,CAAC,WAAW,EAAE,gBAAgB,CAAC;QACjE,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC;AAE7D,QAAA,IAAI;YACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,KAA2C,CAAC;AAC9E,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;AAE1D,YAAA,IAAI,CAAC,IAAI,CAAC,CAAA,eAAA,EAAkB,GAAG,CAAC,QAAQ,CAAK,EAAA,EAAA,cAAc,CAAC,UAAU,CAAC,CAAA,CAAA,CAAG,CAAC;;AAC3E,QAAA,OAAO,KAAU,EAAE;;AAEnB,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;KAEnB;AACF,CAAA;;;;"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { Plugin, OutputOptions } from 'rollup';
|
|
2
|
+
import { type StatsOptions } from 'rollup-plugin-stats/extract';
|
|
2
3
|
import type { BundleTransformOptions } from './transform';
|
|
3
|
-
|
|
4
|
+
import { type StatsWrite } from './write';
|
|
5
|
+
type WebpackStatsOptions = {
|
|
4
6
|
/**
|
|
5
7
|
* JSON file output fileName
|
|
6
8
|
* default: webpack-stats.json
|
|
7
9
|
*/
|
|
8
10
|
fileName?: string;
|
|
9
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Custom file writer
|
|
13
|
+
* @default - fs.write(FILENAME, JSON.stringify(STATS, null, 2));
|
|
14
|
+
*/
|
|
15
|
+
write?: StatsWrite;
|
|
16
|
+
} & Omit<StatsOptions, "source"> & BundleTransformOptions;
|
|
10
17
|
type WebpackStatsOptionsOrBuilder = WebpackStatsOptions | ((outputOptions: OutputOptions) => WebpackStatsOptions);
|
|
11
18
|
export declare const webpackStats: (options?: WebpackStatsOptionsOrBuilder) => Plugin;
|
|
12
19
|
export {};
|
package/dist/transform.cjs
CHANGED
|
@@ -1,225 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var
|
|
3
|
+
require('path');
|
|
4
|
+
var transform = require('./chunks/transform.cjs');
|
|
5
|
+
require('node:path');
|
|
6
|
+
require('node:crypto');
|
|
5
7
|
|
|
6
|
-
const HASH_LENGTH = 7;
|
|
7
|
-
/**
|
|
8
|
-
* Get content byte size
|
|
9
|
-
*/
|
|
10
|
-
function getByteSize(content) {
|
|
11
|
-
if (typeof content === 'string') {
|
|
12
|
-
return Buffer.from(content).length;
|
|
13
|
-
}
|
|
14
|
-
return content?.length || 0;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Generate a 7 chars hash from a filepath
|
|
18
|
-
*/
|
|
19
|
-
function getHash(filepath) {
|
|
20
|
-
const digest = crypto.createHash('sha256');
|
|
21
|
-
return digest.update(Buffer.from(filepath)).digest('hex').substr(0, HASH_LENGTH);
|
|
22
|
-
}
|
|
23
|
-
function getChunkId(chunk) {
|
|
24
|
-
let value = chunk.name;
|
|
25
|
-
// Use entry module relative path
|
|
26
|
-
if (chunk.moduleIds?.length > 0) {
|
|
27
|
-
const absoluteModulePath = chunk.moduleIds[chunk.moduleIds.length - 1];
|
|
28
|
-
value = path.relative(process.cwd(), absoluteModulePath);
|
|
29
|
-
}
|
|
30
|
-
return getHash([chunk, value].join('-'));
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Check if filepath should be excluded based on a config
|
|
34
|
-
*/
|
|
35
|
-
function checkExcludeFilepath(filepath, option) {
|
|
36
|
-
if (!option) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
if (Array.isArray(option)) {
|
|
40
|
-
let res = false;
|
|
41
|
-
for (let i = 0; i <= option.length - 1 && res === false; i++) {
|
|
42
|
-
res = checkExcludeFilepath(filepath, option[i]);
|
|
43
|
-
}
|
|
44
|
-
return res;
|
|
45
|
-
}
|
|
46
|
-
if (typeof option === 'function') {
|
|
47
|
-
return option(filepath);
|
|
48
|
-
}
|
|
49
|
-
if (typeof option === 'string') {
|
|
50
|
-
return Boolean(filepath.match(option));
|
|
51
|
-
}
|
|
52
|
-
if ('test' in option) {
|
|
53
|
-
return option.test(filepath);
|
|
54
|
-
}
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
8
|
|
|
58
|
-
/**
|
|
59
|
-
* Recursivily check if a chunk is async based on the chunks issuers
|
|
60
|
-
*/
|
|
61
|
-
const lookupChunkAsync = (chunk, chunksIssuers) => {
|
|
62
|
-
if (chunk.isDynamicEntry) {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
if (chunk.isEntry) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
const chunkIssuers = chunksIssuers[chunk.fileName];
|
|
69
|
-
/**
|
|
70
|
-
* A sync chunk without issuer chunks, is sync
|
|
71
|
-
*/
|
|
72
|
-
if (!chunkIssuers) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {
|
|
76
|
-
return chunkIssuer.isDynamicEntry === false;
|
|
77
|
-
});
|
|
78
|
-
/**
|
|
79
|
-
* A sync chunk with all the chunk issuer async, is async
|
|
80
|
-
*/
|
|
81
|
-
if (syncChunksIssuers.length === 0) {
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Recursively lookup for sync loads on the 2nd level issuers
|
|
86
|
-
* - if at least one issuer is sync, the chunk is sync
|
|
87
|
-
* - if none of the issuers are sync, the chunk is async
|
|
88
|
-
*/
|
|
89
|
-
let isAsync = true;
|
|
90
|
-
for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {
|
|
91
|
-
isAsync = lookupChunkAsync(syncChunksIssuers[i], chunksIssuers);
|
|
92
|
-
}
|
|
93
|
-
return isAsync;
|
|
94
|
-
};
|
|
95
|
-
/**
|
|
96
|
-
* Store transformed sources
|
|
97
|
-
*/
|
|
98
|
-
class TransformSources {
|
|
99
|
-
constructor() {
|
|
100
|
-
this.entries = {};
|
|
101
|
-
}
|
|
102
|
-
entries = {};
|
|
103
|
-
push(id, source) {
|
|
104
|
-
this.entries[id] = source;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Get asset source
|
|
108
|
-
*/
|
|
109
|
-
getByAsset = (asset) => {
|
|
110
|
-
return this.entries[asset.name];
|
|
111
|
-
};
|
|
112
|
-
/**
|
|
113
|
-
* Get chunk source
|
|
114
|
-
*/
|
|
115
|
-
getByChunk = (chunk) => {
|
|
116
|
-
return this.entries[chunk.id];
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* Get module source
|
|
120
|
-
*/
|
|
121
|
-
getByModule = (module) => {
|
|
122
|
-
return this.entries[module.name];
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
const defaultTransform = (stats) => stats;
|
|
126
|
-
const bundleToWebpackStats = (bundle, pluginOptions) => {
|
|
127
|
-
const options = { moduleOriginalSize: false, ...pluginOptions };
|
|
128
|
-
const { excludeAssets, excludeModules, moduleOriginalSize, transform = defaultTransform } = options;
|
|
129
|
-
const assets = [];
|
|
130
|
-
const chunks = [];
|
|
131
|
-
const moduleByFileName = {};
|
|
132
|
-
const sources = new TransformSources();
|
|
133
|
-
const chunksIssuers = {};
|
|
134
|
-
const entries = Object.values(bundle);
|
|
135
|
-
// Collect metadata
|
|
136
|
-
entries.forEach((entry) => {
|
|
137
|
-
if (entry.type === 'chunk') {
|
|
138
|
-
entry.imports?.forEach((chunkDependency) => {
|
|
139
|
-
if (!chunksIssuers[chunkDependency]) {
|
|
140
|
-
chunksIssuers[chunkDependency] = [];
|
|
141
|
-
}
|
|
142
|
-
chunksIssuers[chunkDependency].push(entry);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
// Process data
|
|
147
|
-
entries.forEach((entry) => {
|
|
148
|
-
if (entry.type === 'chunk') {
|
|
149
|
-
if (checkExcludeFilepath(entry.fileName, excludeAssets)) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
assets.push({
|
|
153
|
-
name: entry.fileName,
|
|
154
|
-
size: getByteSize(entry.code),
|
|
155
|
-
});
|
|
156
|
-
sources.push(entry.fileName, entry);
|
|
157
|
-
const chunkId = getChunkId(entry);
|
|
158
|
-
const chunkAsync = lookupChunkAsync(entry, chunksIssuers);
|
|
159
|
-
chunks.push({
|
|
160
|
-
id: chunkId,
|
|
161
|
-
entry: entry.isEntry,
|
|
162
|
-
initial: !chunkAsync,
|
|
163
|
-
files: [entry.fileName],
|
|
164
|
-
names: [entry.name],
|
|
165
|
-
});
|
|
166
|
-
sources.push(chunkId, entry);
|
|
167
|
-
Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {
|
|
168
|
-
if (checkExcludeFilepath(modulePath, excludeModules)) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
// Remove unexpected rollup null prefix
|
|
172
|
-
const normalizedModulePath = modulePath.replace('\u0000', '');
|
|
173
|
-
const relativeModulePath = path.relative(process.cwd(), normalizedModulePath);
|
|
174
|
-
// Match webpack output - add current directory prefix for child modules
|
|
175
|
-
const relativeModulePathWithPrefix = relativeModulePath.match(/^\.\./)
|
|
176
|
-
? relativeModulePath
|
|
177
|
-
: `.${path.sep}${relativeModulePath}`;
|
|
178
|
-
const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];
|
|
179
|
-
if (moduleEntry) {
|
|
180
|
-
moduleEntry.chunks.push(chunkId);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
moduleByFileName[relativeModulePathWithPrefix] = {
|
|
184
|
-
name: relativeModulePathWithPrefix,
|
|
185
|
-
size: moduleOriginalSize
|
|
186
|
-
? moduleInfo.originalLength
|
|
187
|
-
: moduleInfo.renderedLength,
|
|
188
|
-
chunks: [chunkId],
|
|
189
|
-
};
|
|
190
|
-
sources.push(relativeModulePathWithPrefix, { fileName: modulePath, ...moduleInfo });
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
else if (entry.type === 'asset') {
|
|
195
|
-
if (checkExcludeFilepath(entry.fileName, excludeAssets)) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
assets.push({
|
|
199
|
-
name: entry.fileName,
|
|
200
|
-
size: getByteSize(entry.source.toString()),
|
|
201
|
-
});
|
|
202
|
-
sources.push(entry.fileName, entry);
|
|
203
|
-
}
|
|
204
|
-
else ;
|
|
205
|
-
});
|
|
206
|
-
const stats = {
|
|
207
|
-
builtAt: Date.now(),
|
|
208
|
-
assets,
|
|
209
|
-
chunks,
|
|
210
|
-
modules: Object.values(moduleByFileName),
|
|
211
|
-
};
|
|
212
|
-
let result;
|
|
213
|
-
try {
|
|
214
|
-
result = transform(stats, sources, bundle);
|
|
215
|
-
}
|
|
216
|
-
catch (error) {
|
|
217
|
-
console.error('Custom transform failed! Returning stats without any transforms.', error);
|
|
218
|
-
result = stats;
|
|
219
|
-
}
|
|
220
|
-
return result;
|
|
221
|
-
};
|
|
222
9
|
|
|
223
|
-
exports.bundleToWebpackStats = bundleToWebpackStats;
|
|
224
|
-
exports.lookupChunkAsync = lookupChunkAsync;
|
|
10
|
+
exports.bundleToWebpackStats = transform.bundleToWebpackStats;
|
|
11
|
+
exports.lookupChunkAsync = transform.lookupChunkAsync;
|
|
225
12
|
//# sourceMappingURL=transform.cjs.map
|
package/dist/transform.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.cjs","sources":[
|
|
1
|
+
{"version":3,"file":"transform.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
package/dist/transform.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { OutputAsset, OutputBundle, OutputChunk, RenderedModule } from 'rollup';
|
|
2
|
-
import type { ExcludeFilepathOption } from './utils';
|
|
3
2
|
export type WebpackStatsFilteredAsset = {
|
|
4
3
|
name: string;
|
|
5
4
|
size?: number;
|
|
@@ -67,14 +66,6 @@ export type BundleTransformOptions = {
|
|
|
67
66
|
* default: false
|
|
68
67
|
*/
|
|
69
68
|
moduleOriginalSize?: boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Exclude matching assets
|
|
72
|
-
*/
|
|
73
|
-
excludeAssets?: ExcludeFilepathOption;
|
|
74
|
-
/**
|
|
75
|
-
* Exclude matching modules
|
|
76
|
-
*/
|
|
77
|
-
excludeModules?: ExcludeFilepathOption;
|
|
78
69
|
/**
|
|
79
70
|
* Callback function to access and mutate the resulting stats after the transformation
|
|
80
71
|
*/
|
package/dist/transform.mjs
CHANGED
|
@@ -1,222 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Get content byte size
|
|
7
|
-
*/
|
|
8
|
-
function getByteSize(content) {
|
|
9
|
-
if (typeof content === 'string') {
|
|
10
|
-
return Buffer.from(content).length;
|
|
11
|
-
}
|
|
12
|
-
return content?.length || 0;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Generate a 7 chars hash from a filepath
|
|
16
|
-
*/
|
|
17
|
-
function getHash(filepath) {
|
|
18
|
-
const digest = crypto.createHash('sha256');
|
|
19
|
-
return digest.update(Buffer.from(filepath)).digest('hex').substr(0, HASH_LENGTH);
|
|
20
|
-
}
|
|
21
|
-
function getChunkId(chunk) {
|
|
22
|
-
let value = chunk.name;
|
|
23
|
-
// Use entry module relative path
|
|
24
|
-
if (chunk.moduleIds?.length > 0) {
|
|
25
|
-
const absoluteModulePath = chunk.moduleIds[chunk.moduleIds.length - 1];
|
|
26
|
-
value = path.relative(process.cwd(), absoluteModulePath);
|
|
27
|
-
}
|
|
28
|
-
return getHash([chunk, value].join('-'));
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Check if filepath should be excluded based on a config
|
|
32
|
-
*/
|
|
33
|
-
function checkExcludeFilepath(filepath, option) {
|
|
34
|
-
if (!option) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
if (Array.isArray(option)) {
|
|
38
|
-
let res = false;
|
|
39
|
-
for (let i = 0; i <= option.length - 1 && res === false; i++) {
|
|
40
|
-
res = checkExcludeFilepath(filepath, option[i]);
|
|
41
|
-
}
|
|
42
|
-
return res;
|
|
43
|
-
}
|
|
44
|
-
if (typeof option === 'function') {
|
|
45
|
-
return option(filepath);
|
|
46
|
-
}
|
|
47
|
-
if (typeof option === 'string') {
|
|
48
|
-
return Boolean(filepath.match(option));
|
|
49
|
-
}
|
|
50
|
-
if ('test' in option) {
|
|
51
|
-
return option.test(filepath);
|
|
52
|
-
}
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Recursivily check if a chunk is async based on the chunks issuers
|
|
58
|
-
*/
|
|
59
|
-
const lookupChunkAsync = (chunk, chunksIssuers) => {
|
|
60
|
-
if (chunk.isDynamicEntry) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
if (chunk.isEntry) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
const chunkIssuers = chunksIssuers[chunk.fileName];
|
|
67
|
-
/**
|
|
68
|
-
* A sync chunk without issuer chunks, is sync
|
|
69
|
-
*/
|
|
70
|
-
if (!chunkIssuers) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
const syncChunksIssuers = chunkIssuers.filter((chunkIssuer) => {
|
|
74
|
-
return chunkIssuer.isDynamicEntry === false;
|
|
75
|
-
});
|
|
76
|
-
/**
|
|
77
|
-
* A sync chunk with all the chunk issuer async, is async
|
|
78
|
-
*/
|
|
79
|
-
if (syncChunksIssuers.length === 0) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Recursively lookup for sync loads on the 2nd level issuers
|
|
84
|
-
* - if at least one issuer is sync, the chunk is sync
|
|
85
|
-
* - if none of the issuers are sync, the chunk is async
|
|
86
|
-
*/
|
|
87
|
-
let isAsync = true;
|
|
88
|
-
for (let i = 0; i < syncChunksIssuers.length && isAsync; i++) {
|
|
89
|
-
isAsync = lookupChunkAsync(syncChunksIssuers[i], chunksIssuers);
|
|
90
|
-
}
|
|
91
|
-
return isAsync;
|
|
92
|
-
};
|
|
93
|
-
/**
|
|
94
|
-
* Store transformed sources
|
|
95
|
-
*/
|
|
96
|
-
class TransformSources {
|
|
97
|
-
constructor() {
|
|
98
|
-
this.entries = {};
|
|
99
|
-
}
|
|
100
|
-
entries = {};
|
|
101
|
-
push(id, source) {
|
|
102
|
-
this.entries[id] = source;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Get asset source
|
|
106
|
-
*/
|
|
107
|
-
getByAsset = (asset) => {
|
|
108
|
-
return this.entries[asset.name];
|
|
109
|
-
};
|
|
110
|
-
/**
|
|
111
|
-
* Get chunk source
|
|
112
|
-
*/
|
|
113
|
-
getByChunk = (chunk) => {
|
|
114
|
-
return this.entries[chunk.id];
|
|
115
|
-
};
|
|
116
|
-
/**
|
|
117
|
-
* Get module source
|
|
118
|
-
*/
|
|
119
|
-
getByModule = (module) => {
|
|
120
|
-
return this.entries[module.name];
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
const defaultTransform = (stats) => stats;
|
|
124
|
-
const bundleToWebpackStats = (bundle, pluginOptions) => {
|
|
125
|
-
const options = { moduleOriginalSize: false, ...pluginOptions };
|
|
126
|
-
const { excludeAssets, excludeModules, moduleOriginalSize, transform = defaultTransform } = options;
|
|
127
|
-
const assets = [];
|
|
128
|
-
const chunks = [];
|
|
129
|
-
const moduleByFileName = {};
|
|
130
|
-
const sources = new TransformSources();
|
|
131
|
-
const chunksIssuers = {};
|
|
132
|
-
const entries = Object.values(bundle);
|
|
133
|
-
// Collect metadata
|
|
134
|
-
entries.forEach((entry) => {
|
|
135
|
-
if (entry.type === 'chunk') {
|
|
136
|
-
entry.imports?.forEach((chunkDependency) => {
|
|
137
|
-
if (!chunksIssuers[chunkDependency]) {
|
|
138
|
-
chunksIssuers[chunkDependency] = [];
|
|
139
|
-
}
|
|
140
|
-
chunksIssuers[chunkDependency].push(entry);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
// Process data
|
|
145
|
-
entries.forEach((entry) => {
|
|
146
|
-
if (entry.type === 'chunk') {
|
|
147
|
-
if (checkExcludeFilepath(entry.fileName, excludeAssets)) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
assets.push({
|
|
151
|
-
name: entry.fileName,
|
|
152
|
-
size: getByteSize(entry.code),
|
|
153
|
-
});
|
|
154
|
-
sources.push(entry.fileName, entry);
|
|
155
|
-
const chunkId = getChunkId(entry);
|
|
156
|
-
const chunkAsync = lookupChunkAsync(entry, chunksIssuers);
|
|
157
|
-
chunks.push({
|
|
158
|
-
id: chunkId,
|
|
159
|
-
entry: entry.isEntry,
|
|
160
|
-
initial: !chunkAsync,
|
|
161
|
-
files: [entry.fileName],
|
|
162
|
-
names: [entry.name],
|
|
163
|
-
});
|
|
164
|
-
sources.push(chunkId, entry);
|
|
165
|
-
Object.entries(entry.modules).forEach(([modulePath, moduleInfo]) => {
|
|
166
|
-
if (checkExcludeFilepath(modulePath, excludeModules)) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
// Remove unexpected rollup null prefix
|
|
170
|
-
const normalizedModulePath = modulePath.replace('\u0000', '');
|
|
171
|
-
const relativeModulePath = path.relative(process.cwd(), normalizedModulePath);
|
|
172
|
-
// Match webpack output - add current directory prefix for child modules
|
|
173
|
-
const relativeModulePathWithPrefix = relativeModulePath.match(/^\.\./)
|
|
174
|
-
? relativeModulePath
|
|
175
|
-
: `.${path.sep}${relativeModulePath}`;
|
|
176
|
-
const moduleEntry = moduleByFileName[relativeModulePathWithPrefix];
|
|
177
|
-
if (moduleEntry) {
|
|
178
|
-
moduleEntry.chunks.push(chunkId);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
moduleByFileName[relativeModulePathWithPrefix] = {
|
|
182
|
-
name: relativeModulePathWithPrefix,
|
|
183
|
-
size: moduleOriginalSize
|
|
184
|
-
? moduleInfo.originalLength
|
|
185
|
-
: moduleInfo.renderedLength,
|
|
186
|
-
chunks: [chunkId],
|
|
187
|
-
};
|
|
188
|
-
sources.push(relativeModulePathWithPrefix, { fileName: modulePath, ...moduleInfo });
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
else if (entry.type === 'asset') {
|
|
193
|
-
if (checkExcludeFilepath(entry.fileName, excludeAssets)) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
assets.push({
|
|
197
|
-
name: entry.fileName,
|
|
198
|
-
size: getByteSize(entry.source.toString()),
|
|
199
|
-
});
|
|
200
|
-
sources.push(entry.fileName, entry);
|
|
201
|
-
}
|
|
202
|
-
else ;
|
|
203
|
-
});
|
|
204
|
-
const stats = {
|
|
205
|
-
builtAt: Date.now(),
|
|
206
|
-
assets,
|
|
207
|
-
chunks,
|
|
208
|
-
modules: Object.values(moduleByFileName),
|
|
209
|
-
};
|
|
210
|
-
let result;
|
|
211
|
-
try {
|
|
212
|
-
result = transform(stats, sources, bundle);
|
|
213
|
-
}
|
|
214
|
-
catch (error) {
|
|
215
|
-
console.error('Custom transform failed! Returning stats without any transforms.', error);
|
|
216
|
-
result = stats;
|
|
217
|
-
}
|
|
218
|
-
return result;
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
export { bundleToWebpackStats, lookupChunkAsync };
|
|
1
|
+
import 'path';
|
|
2
|
+
export { b as bundleToWebpackStats, l as lookupChunkAsync } from './chunks/transform.mjs';
|
|
3
|
+
import 'node:path';
|
|
4
|
+
import 'node:crypto';
|
|
222
5
|
//# sourceMappingURL=transform.mjs.map
|
package/dist/transform.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.mjs","sources":[
|
|
1
|
+
{"version":3,"file":"transform.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -10,8 +10,7 @@ export declare function getHash(filepath: string): string;
|
|
|
10
10
|
export declare function getChunkId(chunk: OutputChunk): string;
|
|
11
11
|
type ExcludeFilepathParam = string | RegExp | ((filepath: string) => boolean);
|
|
12
12
|
export type ExcludeFilepathOption = ExcludeFilepathParam | Array<ExcludeFilepathParam>;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export declare function checkExcludeFilepath(filepath: string, option?: ExcludeFilepathOption): boolean;
|
|
13
|
+
export declare function round(value: number, precision?: number): number;
|
|
14
|
+
export declare function formatFileSize(value?: number | null): string;
|
|
15
|
+
export declare function resolveFilepath(fileName?: string, outputDir?: string): string;
|
|
17
16
|
export {};
|
package/dist/write.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type StatsWriteResponse = {
|
|
2
|
+
filepath: string;
|
|
3
|
+
content: string;
|
|
4
|
+
};
|
|
5
|
+
export type StatsWrite = (filepath: string, stats: Record<string, unknown>) => StatsWriteResponse;
|
|
6
|
+
export declare function statsWrite<T extends Record<string, unknown> = Record<string, unknown>>(filepath: string, stats: T): Promise<StatsWriteResponse>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rollup-plugin-webpack-stats",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -38,10 +38,11 @@
|
|
|
38
38
|
"node": ">=18"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
|
+
"prebuild": "rimraf ./dist",
|
|
41
42
|
"build": "rollup -c rollup.config.mjs",
|
|
42
43
|
"lint": "exit 0",
|
|
43
44
|
"test:unit": "vitest test/unit",
|
|
44
|
-
"test:package": "
|
|
45
|
+
"test:package": "cd test/package && vitest",
|
|
45
46
|
"bump": "./scripts/bump.sh",
|
|
46
47
|
"release": "./scripts/release.sh"
|
|
47
48
|
},
|
|
@@ -57,19 +58,24 @@
|
|
|
57
58
|
"trailingComma": "es5"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"@release-it/conventional-changelog": "
|
|
61
|
+
"@release-it/conventional-changelog": "10.0.0",
|
|
61
62
|
"@rollup/plugin-typescript": "12.1.2",
|
|
62
63
|
"@tsconfig/node18": "18.2.4",
|
|
63
|
-
"@types/node": "22.10.
|
|
64
|
+
"@types/node": "22.10.5",
|
|
64
65
|
"dotenv": "16.4.7",
|
|
65
66
|
"husky": "9.1.7",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
67
|
+
"memfs": "^4.15.1",
|
|
68
|
+
"release-it": "18.1.1",
|
|
69
|
+
"rimraf": "6.0.1",
|
|
70
|
+
"rollup": "4.30.1",
|
|
68
71
|
"tslib": "2.8.1",
|
|
69
|
-
"typescript": "5.7.
|
|
72
|
+
"typescript": "5.7.3",
|
|
70
73
|
"vitest": "2.1.8"
|
|
71
74
|
},
|
|
72
75
|
"peerDependencies": {
|
|
73
76
|
"rollup": "^3.0.0 || ^4.0.0"
|
|
77
|
+
},
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"rollup-plugin-stats": "1.2.1"
|
|
74
80
|
}
|
|
75
81
|
}
|