Skip to content

Commit 5ede5f2

Browse files
committed
Add filterSummary (fixes #19 and #20), v3.3.0
1 parent 1accfe7 commit 5ede5f2

8 files changed

Lines changed: 198 additions & 126 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
44

5-
### UNRELEASED
5+
### [3.3.0](https://github.com/doesdev/rollup-plugin-analyzer/compare/3.2.3...3.3.0)
6+
7+
> 8 July 2020
8+
9+
- Add `filterSummary` option (#19 && #20)
10+
- Fix `origSize`, `bundleOrigSize`, and `bundleReduction` (was apparently borked)
611
- Remove Rollup 0.60.0 from tests
712
- Fix incorrect key names in `analysisObject` docs
813
- Clarify `filter` usage

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,12 @@ module count: 5
152152
- If array it checks the same for each string in the array
153153
- If function, return a boolean to indicate if a module should be in analysis results
154154
- This only suppresses the modules details, it does not affect the summary output
155-
- If you would like it to filter from summary info as well, let us know in [#19](https://github.com/doesdev/rollup-plugin-analyzer/issues/19)
155+
- If you would like it to filter from summary info as well set `filterSummary` to `true`
156156
- notes: Function receives `module` object specified below, should return boolean
157+
- **filterSummary** - *optional*
158+
- type: Boolean
159+
- default: `false`
160+
- description: If `true` the `filter` option will also remove any filtered out module data from the summary
157161
- **root** - *optional*
158162
- type: String
159163
- default: `process.cwd()`

index.d.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,22 @@ import { Plugin } from "rollup";
33
declare const analyzer: (options?: AnalyzerOptions) => Plugin;
44
export default analyzer;
55

6+
export interface Module {
7+
id: string;
8+
size: number;
9+
origSize: number;
10+
dependents: string[];
11+
percent: number;
12+
reduction: number;
13+
usedExports: string[];
14+
unusedExports: string[];
15+
}
16+
617
export interface AnalyzerOptions {
718
stdout?: boolean;
819
limit?: number;
9-
filter?: string | string[] | ((id: string) => boolean);
20+
filter?: string | string[] | ((moduleObject: Module) => boolean);
21+
filterSummary?: boolean;
1022
root?: string;
1123
hideDeps?: boolean;
1224
showExports?: boolean;
@@ -24,14 +36,3 @@ export interface AnalysisObject {
2436
moduleCount: number;
2537
modules: Module[];
2638
}
27-
28-
export interface Module {
29-
id: string;
30-
size: number;
31-
origSize: number;
32-
dependents: string[];
33-
percent: number;
34-
reduction: number;
35-
usedExports: string[];
36-
unusedExports: string[];
37-
}

index.js

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const buf = ' ';
44
const tab = ' ';
55
const borderX = `${Array(30).join('-')}\n`;
6+
67
const formatBytes = (bytes) => {
78
if (bytes === 0) return '0 Byte'
89
const k = 1000;
@@ -11,9 +12,25 @@ const formatBytes = (bytes) => {
1112
const i = Math.floor(Math.log(bytes) / Math.log(k));
1213
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
1314
};
14-
const shakenPct = (n, o) => Math.max((100 - ((n / o) * 100)).toFixed(2), 0);
15+
16+
const shakenPct = (n = 0, o = 0) => {
17+
const pct = Math.max((100 - ((n / o) * 100)).toFixed(2), 0);
18+
return Number.isNaN(pct) ? 0 : pct
19+
};
20+
1521
const match = (str, check) => str.indexOf(check) !== -1;
1622

23+
const sizeOrCodeSize = (size, code) => {
24+
if (size || size === 0) return size
25+
return code ? Buffer.byteLength(code, 'utf8') : 0
26+
};
27+
28+
const filterByType = {
29+
function: (filter, m) => filter(m),
30+
array: (filter, m) => filter.some((f) => match(m.id, f)),
31+
string: (filter, m) => match(m.id, filter)
32+
};
33+
1734
const reporter = (analysis, opts) => {
1835
const { hideDeps, root, showExports, summaryOnly } = opts || {};
1936

@@ -72,57 +89,67 @@ const reporter = (analysis, opts) => {
7289
};
7390

7491
const analyzer = (bundle, opts = {}) => {
75-
const { limit, filter } = opts;
76-
let { root, transformModuleId } = opts;
77-
root = root || (process && process.cwd ? process.cwd() : null);
78-
if (typeof transformModuleId !== 'function') transformModuleId = undefined;
79-
80-
const deps = {};
92+
const { limit, filter, transformModuleId, filterSummary } = opts;
93+
const root = opts.root || (process && process.cwd ? process.cwd() : null);
94+
const idMod = typeof transformModuleId === 'function' && transformModuleId;
95+
const filterType = Array.isArray(filter) ? 'array' : typeof filter;
96+
const applyFilter = filterByType[filterType];
8197
const bundleModules = bundle.modules || (bundle.cache || {}).modules || [];
82-
const moduleCount = bundleModules.length;
98+
const deps = {};
8399

100+
let tmpBdlSize = 0;
84101
let bundleSize = 0;
85102
let bundleOrigSize = 0;
86103

87104
let modules = bundleModules.map((m, i) => {
105+
const id = idMod ? idMod(m.id.replace(root, '')) : m.id.replace(root, '');
88106
const {
89-
originalLength: origSize,
107+
originalLength,
90108
renderedLength,
91-
code,
92109
renderedExports,
93-
removedExports
110+
removedExports,
111+
originalCode,
112+
code
94113
} = m;
95-
let { id } = m;
96-
id = id.replace(root, '');
97-
if (transformModuleId) id = transformModuleId(id);
98-
let size = renderedLength;
99-
if (!size && size !== 0) size = code ? Buffer.byteLength(code, 'utf8') : 0;
100-
bundleSize += size;
101-
bundleOrigSize += origSize;
102114

103-
if (Array.isArray(filter) && !filter.some((f) => match(id, f))) return null
104-
if (typeof filter === 'string' && !match(id, filter)) return null
115+
const size = sizeOrCodeSize(renderedLength, code);
116+
const origSize = sizeOrCodeSize(originalLength, originalCode);
117+
118+
tmpBdlSize += size;
105119

106120
m.dependencies.forEach((d) => {
107-
d = d.replace(root, '');
108-
if (transformModuleId) d = transformModuleId(d);
121+
d = idMod ? idMod(d.replace(root, '')) : d.replace(root, '');
109122
deps[d] = deps[d] || [];
110123
deps[d].push(id);
111124
});
112125

113126
return { id, size, origSize, renderedExports, removedExports }
114-
}).filter((m) => m);
127+
}).filter((m) => m).sort((a, b) => b.size - a.size);
115128

116-
modules.sort((a, b) => b.size - a.size);
117129
if (limit || limit === 0) modules = modules.slice(0, limit);
118-
modules.forEach((m) => {
130+
131+
modules = modules.map((m) => {
119132
m.dependents = deps[m.id] || [];
120-
m.percent = Math.min(((m.size / bundleSize) * 100).toFixed(2), 100);
133+
m.percent = Math.min(((m.size / tmpBdlSize) * 100).toFixed(2), 100);
121134
m.reduction = shakenPct(m.size, m.origSize);
122-
});
123-
if (typeof filter === 'function') modules = modules.filter(filter);
135+
136+
const filtered = applyFilter && !applyFilter(filter, m);
137+
if (filtered && filterSummary) return null
138+
139+
bundleSize += m.size;
140+
bundleOrigSize += m.origSize;
141+
142+
return filtered ? null : m
143+
}).filter((m) => m);
144+
145+
if (filterSummary) {
146+
modules.forEach((m) => {
147+
m.percent = Math.min(((m.size / bundleSize) * 100).toFixed(2), 100);
148+
});
149+
}
124150

125151
const bundleReduction = shakenPct(bundleSize, bundleOrigSize);
152+
const moduleCount = (filterSummary ? modules : bundleModules).length;
126153

127154
return { bundleSize, bundleOrigSize, bundleReduction, modules, moduleCount }
128155
};

module.js

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const buf = ' '
44
const tab = ' '
55
const borderX = `${Array(30).join('-')}\n`
6+
67
const formatBytes = (bytes) => {
78
if (bytes === 0) return '0 Byte'
89
const k = 1000
@@ -11,9 +12,25 @@ const formatBytes = (bytes) => {
1112
const i = Math.floor(Math.log(bytes) / Math.log(k))
1213
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
1314
}
14-
const shakenPct = (n, o) => Math.max((100 - ((n / o) * 100)).toFixed(2), 0)
15+
16+
const shakenPct = (n = 0, o = 0) => {
17+
const pct = Math.max((100 - ((n / o) * 100)).toFixed(2), 0)
18+
return Number.isNaN(pct) ? 0 : pct
19+
}
20+
1521
const match = (str, check) => str.indexOf(check) !== -1
1622

23+
const sizeOrCodeSize = (size, code) => {
24+
if (size || size === 0) return size
25+
return code ? Buffer.byteLength(code, 'utf8') : 0
26+
}
27+
28+
const filterByType = {
29+
function: (filter, m) => filter(m),
30+
array: (filter, m) => filter.some((f) => match(m.id, f)),
31+
string: (filter, m) => match(m.id, filter)
32+
}
33+
1734
const reporter = (analysis, opts) => {
1835
const { hideDeps, root, showExports, summaryOnly } = opts || {}
1936

@@ -72,57 +89,67 @@ const reporter = (analysis, opts) => {
7289
}
7390

7491
const analyzer = (bundle, opts = {}) => {
75-
const { limit, filter } = opts
76-
let { root, transformModuleId } = opts
77-
root = root || (process && process.cwd ? process.cwd() : null)
78-
if (typeof transformModuleId !== 'function') transformModuleId = undefined
79-
80-
const deps = {}
92+
const { limit, filter, transformModuleId, filterSummary } = opts
93+
const root = opts.root || (process && process.cwd ? process.cwd() : null)
94+
const idMod = typeof transformModuleId === 'function' && transformModuleId
95+
const filterType = Array.isArray(filter) ? 'array' : typeof filter
96+
const applyFilter = filterByType[filterType]
8197
const bundleModules = bundle.modules || (bundle.cache || {}).modules || []
82-
const moduleCount = bundleModules.length
98+
const deps = {}
8399

100+
let tmpBdlSize = 0
84101
let bundleSize = 0
85102
let bundleOrigSize = 0
86103

87104
let modules = bundleModules.map((m, i) => {
105+
const id = idMod ? idMod(m.id.replace(root, '')) : m.id.replace(root, '')
88106
const {
89-
originalLength: origSize,
107+
originalLength,
90108
renderedLength,
91-
code,
92109
renderedExports,
93-
removedExports
110+
removedExports,
111+
originalCode,
112+
code
94113
} = m
95-
let { id } = m
96-
id = id.replace(root, '')
97-
if (transformModuleId) id = transformModuleId(id)
98-
let size = renderedLength
99-
if (!size && size !== 0) size = code ? Buffer.byteLength(code, 'utf8') : 0
100-
bundleSize += size
101-
bundleOrigSize += origSize
102114

103-
if (Array.isArray(filter) && !filter.some((f) => match(id, f))) return null
104-
if (typeof filter === 'string' && !match(id, filter)) return null
115+
const size = sizeOrCodeSize(renderedLength, code)
116+
const origSize = sizeOrCodeSize(originalLength, originalCode)
117+
118+
tmpBdlSize += size
105119

106120
m.dependencies.forEach((d) => {
107-
d = d.replace(root, '')
108-
if (transformModuleId) d = transformModuleId(d)
121+
d = idMod ? idMod(d.replace(root, '')) : d.replace(root, '')
109122
deps[d] = deps[d] || []
110123
deps[d].push(id)
111124
})
112125

113126
return { id, size, origSize, renderedExports, removedExports }
114-
}).filter((m) => m)
127+
}).filter((m) => m).sort((a, b) => b.size - a.size)
115128

116-
modules.sort((a, b) => b.size - a.size)
117129
if (limit || limit === 0) modules = modules.slice(0, limit)
118-
modules.forEach((m) => {
130+
131+
modules = modules.map((m) => {
119132
m.dependents = deps[m.id] || []
120-
m.percent = Math.min(((m.size / bundleSize) * 100).toFixed(2), 100)
133+
m.percent = Math.min(((m.size / tmpBdlSize) * 100).toFixed(2), 100)
121134
m.reduction = shakenPct(m.size, m.origSize)
122-
})
123-
if (typeof filter === 'function') modules = modules.filter(filter)
135+
136+
const filtered = applyFilter && !applyFilter(filter, m)
137+
if (filtered && filterSummary) return null
138+
139+
bundleSize += m.size
140+
bundleOrigSize += m.origSize
141+
142+
return filtered ? null : m
143+
}).filter((m) => m)
144+
145+
if (filterSummary) {
146+
modules.forEach((m) => {
147+
m.percent = Math.min(((m.size / bundleSize) * 100).toFixed(2), 100)
148+
})
149+
}
124150

125151
const bundleReduction = shakenPct(bundleSize, bundleOrigSize)
152+
const moduleCount = (filterSummary ? modules : bundleModules).length
126153

127154
return { bundleSize, bundleOrigSize, bundleReduction, modules, moduleCount }
128155
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rollup-plugin-analyzer",
3-
"version": "3.2.3",
3+
"version": "3.3.0",
44
"description": "Mad metrics for your rollup bundles, know all the things",
55
"engines": {
66
"node": ">=8.0.0"

test/test.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ rollers.forEach(({ rollup, version, opts, noTreeshake }) => {
104104
assert.is((await analyze(bundle, { filter: hasMatch })).modules.length, 1)
105105
})
106106

107+
test(`${version}: filterSummary with string works`, async (assert) => {
108+
const bundle = await rollup(opts)
109+
const filter = 'jimmy'
110+
const whenFalse = await analyze(bundle, { filter })
111+
const whenTrue = await analyze(bundle, { filter, filterSummary: true })
112+
113+
assert.is(whenFalse.moduleCount, 5)
114+
assert.is(whenTrue.moduleCount, 0)
115+
116+
assert.true(Math.abs(whenFalse.bundleSize - 11436) < 5)
117+
assert.is(whenTrue.bundleSize, 0)
118+
119+
assert.true(Math.abs(whenFalse.bundleOrigSize - 11436) < 5)
120+
assert.is(whenTrue.bundleOrigSize, 0)
121+
})
122+
107123
test(`${version}: transformModuleId works`, async (assert) => {
108124
const bundle = await rollup(opts)
109125
const transformModuleId = (id) => `transformed-${basename(id)}`
@@ -186,7 +202,7 @@ rollers.forEach(({ rollup, version, opts, noTreeshake }) => {
186202
await bundle.write(output)
187203
const imported = results.find((r) => r.id.indexOf(importA) !== -1)
188204
const expectSize = 27
189-
assert.truthy(Math.abs(imported.size - expectSize) < 5)
205+
assert.true(Math.abs(imported.size - expectSize) < 5)
190206
})
191207

192208
test(`${version}: treeshaken bundle filters with callback`, async (assert) => {

0 commit comments

Comments
 (0)