Skip to content

Commit

Permalink
feat: normalize stats before analyzing
Browse files Browse the repository at this point in the history
  • Loading branch information
d4rkr00t committed Jun 20, 2019
1 parent eaf3a30 commit 75ca94c
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 122 deletions.
6 changes: 3 additions & 3 deletions commands/by.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Reporter } from '../lib/reporter';
const { analyze, getStats } = require("../lib");
const validate = require("../lib/validate");
const { log, invalidStatsJson } = require("../lib/console/messages");
const normalizeStats = require("../lib/normalize-stats");

const isDepsChainBy = (depsChain /*: Array<string> */, by /*: string */) => {
return depsChain.indexOf(by) !== -1;
Expand Down Expand Up @@ -44,9 +45,8 @@ module.exports = function byCommand(
reporter /*: Reporter */,
updateProgressBar /*: UpdateProgressBar */ = () => {}
) {
const stats = getStats(statsFilePath);

if (!validate(stats)) {
const stats = normalizeStats(getStats(statsFilePath));
if (!validate(stats.modules)) {
log(invalidStatsJson(statsFilePath));
process.exit(1);
}
Expand Down
6 changes: 3 additions & 3 deletions commands/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const mm = require("micromatch");
const { analyze, getStats } = require("../lib");
const validate = require("../lib/validate");
const { log, invalidStatsJson } = require("../lib/console/messages");
const normalizeStats = require("../lib/normalize-stats");

/*::
import type { UpdateProgressBar } from '../lib/console/progress-bar';
Expand All @@ -28,9 +29,8 @@ module.exports = function defaultCommand(
reporter /*: Reporter */,
updateProgressBar /*: UpdateProgressBar */ = () => {}
) {
const stats = getStats(statsFilePath);

if (!validate(stats)) {
const stats = normalizeStats(getStats(statsFilePath));
if (!validate(stats.modules)) {
log(invalidStatsJson(statsFilePath));
process.exit(1);
}
Expand Down
7 changes: 5 additions & 2 deletions lib/__tests__/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ const fixtures = require("fixturez");
const f = fixtures(__dirname);
const getStats = require("../get-stats");
const analyze = require("../analyze");
const normalizeStats = require("../normalize-stats");

test("should call updateProgressBar correct number of times", t => {
let calls = 0;
const updateProgressBar = ({ progress }) => {
calls++;
};
const stats = analyze(
getStats(f.find("valid-with-multiple-modules.json")),
normalizeStats(getStats(f.find("valid-with-multiple-modules.json"))),
[],
updateProgressBar
);
Expand All @@ -20,7 +21,9 @@ test("should call updateProgressBar correct number of times", t => {
test("should handle stats file with a chunk which has empty modules", t => {
t.snapshot(
analyze(
getStats(f.find("valid-with-empty-modules-in-chunks.json")),
normalizeStats(
getStats(f.find("valid-with-empty-modules-in-chunks.json"))
),
[],
() => {}
)
Expand Down
17 changes: 9 additions & 8 deletions lib/__tests__/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@ const fixtures = require("fixturez");
const f = fixtures(__dirname);
const validate = require("../validate");
const getStats = require("../get-stats");
const normalizeStats = require("../normalize-stats");

test(`should return false for an invalid stats file that doesn't have "reasons" for modules`, t => {
const stats = getStats(f.find("invalid-no-reasons.json"));
t.falsy(validate(stats));
const stats = normalizeStats(getStats(f.find("invalid-no-reasons.json")));
t.falsy(validate(stats.modules));
});

test(`should return false for an invalid stats file that doesn't have niether chunks nor modules`, t => {
const stats = getStats(f.find("empty-stats.json"));
t.falsy(validate(stats));
const stats = normalizeStats(getStats(f.find("empty-stats.json")));
t.falsy(validate(stats.modules));
});

test("should return true for a valid stats file", t => {
const stats = getStats(f.find("valid.json"));
t.truthy(validate(stats));
const stats = normalizeStats(getStats(f.find("valid.json")));
t.truthy(validate(stats.modules));
});

test("should return true for a valid stats file with children", t => {
const stats = getStats(f.find("valid-with-children.json"));
t.truthy(validate(stats));
const stats = normalizeStats(getStats(f.find("valid-with-children.json")));
t.truthy(validate(stats.modules));
});
36 changes: 10 additions & 26 deletions lib/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export type WebpackStats = {
children?: Array<WebpackStats & { id?: string }>
};
export type NormalizedWebpackStats = {
chunks: Chunks,
modules: Array<WebpackModule>,
};
export type WebpackChunk = {
id: number,
size: number,
Expand Down Expand Up @@ -85,7 +90,6 @@ export type Chunks = {

const path = require("path");
const mm = require("micromatch");
const flattenStats = require("./flatten-stats");

const DEFAULT_IGNORE = ["multi *", "*-loader*"];

Expand Down Expand Up @@ -116,13 +120,8 @@ const getModuleType = (name /*?: string */) =>
!name || name.startsWith("multi ")
? "entry"
: isNodeModules(name)
? "module"
: "file";

const flattenChunks = (stats /*: WebpackStats */) /*: Array<WebpackModule> */ =>
stats.chunks && stats.chunks[0].modules
? stats.chunks.reduce((modules, chunk) => modules.concat(chunk.modules), [])
: stats.modules;
? "module"
: "file";

const isNodeModules = (identifier /*: string */) =>
identifier.indexOf("node_modules") > -1;
Expand Down Expand Up @@ -320,29 +319,14 @@ const postProcessModules = (
}, {});
};

function getChunksData(stats /*: WebpackStats */) {
return stats.chunks
? stats.chunks.reduce((acc, chunk) => {
acc[chunk.id] = {
id: chunk.id,
names: chunk.names,
size: chunk.size
};
return acc;
}, {})
: {};
}

module.exports = function analyze(
rawStats /*: WebpackStats */,
normalizedStats /*: NormalizedWebpackStats */,
ignore /*: Array<string> */ = [],
updateProgressBar /*: UpdateProgressBar */ = () => {}
) {
const stats = flattenStats(rawStats);
const chunks = getChunksData(stats);
const rawModules = flattenChunks(stats);
const chunks = normalizedStats.chunks;
const modules = pickFromModules(normalizedStats.modules);
const ignorePatterns = [].concat(DEFAULT_IGNORE).concat(ignore);
const modules = pickFromModules(rawModules);
const joinedModules = joinModules(modules);
const joinedModulesCount = Object.keys(joinedModules).length;
const updateProgressBarWithTotal = (
Expand Down
4 changes: 2 additions & 2 deletions lib/console/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ function invalidStatsJson(file /*: string */) {
chalk.red(
`${errorBadge()} Stats file ${chalk.bold(
`"${file}"`
)} doesn't contain "reasons" why modules are included...`
)} doesn't contain enough information...`
),
"",
`Whybundled needs "reasons" to function properly. To add them check webpack documentation: ${chalk.blue(
`Issue is possibly with missing "reasons" in webpack module stats. To add them check webpack documentation: ${chalk.blue(
"https://webpack.js.org/configuration/stats/#stats"
)}`
];
Expand Down
37 changes: 0 additions & 37 deletions lib/flatten-stats.js

This file was deleted.

38 changes: 38 additions & 0 deletions lib/normalize-stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* @flow */

/*::
import type { WebpackStats, NormalizedWebpackStats } from "./analyze";
*/

module.exports = function normalizeStats(
stats /*: WebpackStats */
) /*: NormalizedWebpackStats */ {
let modules = new Map();
let chunks = {};

(stats.chunks || []).forEach(chunk => {
chunks[chunk.id] = {
id: chunk.id,
names: chunk.names,
size: chunk.size
};

(chunk.modules || []).forEach(m => {
modules.set(m.id, m);
});
});

(stats.modules || []).forEach(m => {
modules.set(m.id, m);
});

(stats.children || []).forEach(child => {
let normalizedChild = normalizeStats(child);
chunks = { ...chunks, ...normalizedChild.chunks };
normalizedChild.modules.forEach(m => {
modules.set(m.id, m);
});
});

return { modules: Array.from(modules.values()), chunks };
};
3 changes: 1 addition & 2 deletions lib/reporter/__tests__/__snapshots__/print.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -1433,14 +1433,13 @@ Generated by [AVA](https://ava.li).
` MODULE bootstrap␊
├─ imported: 2 times␊
├─ deps count: 0␊
├─ size: 235 KiB [for all included files]␊
├─ size: 118 KiB [for all included files]␊
├─ type: [direct]␊
├─ chunks: main␊
├─ locations: ␊
│ └─ ../node_modules/.registry.npmjs.org/bootstrap/␊
│ ␊
├─ files: ␊
│ ├─ css ../node_modules/.registry.npmjs.org/css-loader/0.28.10/node_modules/css-loader!../node_modules/.registry.npmjs.org/postcss-loader/2.1.1/node_modules/postcss-loader/lib!../node_modules/.registry.npmjs.org/bootstrap/4.0.0/node_modules/bootstrap/dist/css/bootstrap.min.css␊
│ ├─ ../node_modules/.registry.npmjs.org/bootstrap/4.0.0/node_modules/bootstrap/dist/css/bootstrap.min.css␊
│ └─ ../node_modules/.registry.npmjs.org/css-loader/0.28.10/node_modules/css-loader!../node_modules/.registry.npmjs.org/postcss-loader/2.1.1/node_modules/postcss-loader/lib!../node_modules/.registry.npmjs.org/bootstrap/4.0.0/node_modules/bootstrap/dist/css/bootstrap.min.css␊
│ ␊
Expand Down
Binary file modified lib/reporter/__tests__/__snapshots__/print.js.snap
Binary file not shown.
25 changes: 18 additions & 7 deletions lib/reporter/__tests__/print.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const f = fixtures(__dirname);
const getStats = require("../../get-stats");
const analyze = require("../../analyze");
const print = require("../print");
const normalizeStats = require("../../normalize-stats");

const createPrint = () => {
const messages = [];
Expand All @@ -15,51 +16,61 @@ const createPrint = () => {
};

test("should properly print reasons without clearName", t => {
const stats = analyze(getStats(f.find("with-external.json")));
const stats = analyze(normalizeStats(getStats(f.find("with-external.json"))));
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
});

test("should properly print simple stats.json", t => {
const stats = analyze(getStats(f.find("example-simple-stats.json")));
const stats = analyze(
normalizeStats(getStats(f.find("example-simple-stats.json")))
);
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
});

test("should properly print multi entry stats.json", t => {
const stats = analyze(getStats(f.find("multi-entry-stats.json")));
const stats = analyze(
normalizeStats(getStats(f.find("multi-entry-stats.json")))
);
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
});

test("should properly print multi entry stats.json with dynamic import", t => {
const stats = analyze(
getStats(f.find("multi-entry-dynamic-import-stats.json"))
normalizeStats(getStats(f.find("multi-entry-dynamic-import-stats.json")))
);
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
});

test("should properly print multi entry stats.json with no chunks information", t => {
const stats = analyze(getStats(f.find("multi-entry-no-chunks-stats.json")));
const stats = analyze(
normalizeStats(getStats(f.find("multi-entry-no-chunks-stats.json")))
);
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
});

test("should properly print stats.json with nested children", t => {
const stats = analyze(getStats(f.find("nested-children-stats.json")));
const stats = analyze(
normalizeStats(getStats(f.find("nested-children-stats.json")))
);
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
});

test("should properly print stats.json with nested children second example", t => {
const stats = analyze(getStats(f.find("nested-children-stats2.json")));
const stats = analyze(
normalizeStats(getStats(f.find("nested-children-stats2.json")))
);
const logger = createPrint();
print(stats.modules, stats.chunks, {}, 0, logger);
t.snapshot(logger());
Expand Down
Loading

0 comments on commit 75ca94c

Please sign in to comment.