Skip to content

Commit

Permalink
BUG: Handle null chunks in webpack stats object. (#111)
Browse files Browse the repository at this point in the history
- Expand type to allow `null` and handle in code. Fixes #110 
- Add regression tests.
  • Loading branch information
ryan-roemer authored Mar 27, 2019
1 parent ebaad26 commit cddcb9a
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 115 deletions.
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
History
=======

## Unreleased

* BUG: Handle `null` chunks in webpack stats object.
[#110](https://github.com/FormidableLabs/inspectpack/issues/110)

## 4.2.0

* Add `commonRoot` to `versions` metadata to indicate what installed paths are relative to.
Expand Down
6 changes: 6 additions & 0 deletions src/lib/actions/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ export abstract class Action {
};

asset.chunks.forEach((chunk) => {
// Skip null chunks, allowing only strings or numbers.
if (chunk === null) { return; }

chunk = chunk.toString(); // force to string.
chunksToAssets[chunk] = chunksToAssets[chunk] || new Set();

Expand All @@ -273,6 +276,9 @@ export abstract class Action {
// Iterate modules and attach as appropriate.
this.modules.forEach((mod) => {
mod.chunks.forEach((chunk) => {
// Skip null chunks, allowing only strings or numbers.
if (chunk === null) { return; }

chunk = chunk.toString(); // force to string.
(chunksToAssets[chunk] || []).forEach((assetName) => {
const assetObj = modulesSetByAsset[assetName];
Expand Down
2 changes: 1 addition & 1 deletion src/lib/interfaces/webpack-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import * as t from "io-ts";
*/

// Common
const RWebpackStatsChunk = t.union([t.string, t.number]);
const RWebpackStatsChunk = t.union([t.string, t.number, t.null]);

export type IWebpackStatsChunk = t.TypeOf<typeof RWebpackStatsChunk>;

Expand Down
256 changes: 142 additions & 114 deletions test/lib/actions/sizes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,126 +271,154 @@ describe("lib/actions/sizes", () => {
});

describe("json", () => {
/*tslint:disable max-line-length*/
const expectedScopedData = {
assets: {
"bundle.js": {
files: [
{
baseName: "@scope/foo/bike.js",
fileName: "scoped/node_modules/@scope/foo/bike.js",
size: {
full: "NUM",
},
},
{
baseName: "@scope/foo/index.js",
fileName: "scoped/node_modules/@scope/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "bar/index.js",
fileName: "scoped/node_modules/bar/index.js",
size: {
full: "NUM",
},
},
{
baseName: "bar/tender.js",
fileName: "scoped/node_modules/bar/tender.js",
size: {
full: "NUM",
},
},
{
baseName: "flattened-foo/index.js",
fileName: "scoped/node_modules/flattened-foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "unscoped-foo/index.js",
fileName: "scoped/node_modules/unscoped-foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "deeper-unscoped/index.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/deeper-unscoped/index.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/car.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/deeper-unscoped/node_modules/foo/car.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/index.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/deeper-unscoped/node_modules/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/car.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/foo/car.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/index.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "uses-foo/index.js",
fileName: "scoped/node_modules/uses-foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "@scope/foo/index.js",
fileName: "scoped/node_modules/uses-foo/node_modules/@scope/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: null,
fileName: "scoped/src/index.js",
size: {
full: "NUM",
},
},
],
meta: {
full: "NUM",
},
},
},
meta: {
full: "NUM",
},
};
/*tslint:enable max-line-length*/

it("displays sizes correctly for scoped packages", () => {
return scopedInstance.template.json()
.then((dataStr) => {
// Inflate to real object and re-use previous test assertions.
const data = JSON.parse(normalizeOutput(JSON_PATH_RE, dataStr));

/*tslint:disable max-line-length*/
expect(data).to.eql({
assets: {
"bundle.js": {
files: [
{
baseName: "@scope/foo/bike.js",
fileName: "scoped/node_modules/@scope/foo/bike.js",
size: {
full: "NUM",
},
},
{
baseName: "@scope/foo/index.js",
fileName: "scoped/node_modules/@scope/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "bar/index.js",
fileName: "scoped/node_modules/bar/index.js",
size: {
full: "NUM",
},
},
{
baseName: "bar/tender.js",
fileName: "scoped/node_modules/bar/tender.js",
size: {
full: "NUM",
},
},
{
baseName: "flattened-foo/index.js",
fileName: "scoped/node_modules/flattened-foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "unscoped-foo/index.js",
fileName: "scoped/node_modules/unscoped-foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "deeper-unscoped/index.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/deeper-unscoped/index.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/car.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/deeper-unscoped/node_modules/foo/car.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/index.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/deeper-unscoped/node_modules/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/car.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/foo/car.js",
size: {
full: "NUM",
},
},
{
baseName: "foo/index.js",
fileName: "scoped/node_modules/unscoped-foo/node_modules/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "uses-foo/index.js",
fileName: "scoped/node_modules/uses-foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: "@scope/foo/index.js",
fileName: "scoped/node_modules/uses-foo/node_modules/@scope/foo/index.js",
size: {
full: "NUM",
},
},
{
baseName: null,
fileName: "scoped/src/index.js",
size: {
full: "NUM",
},
},
],
meta: {
full: "NUM",
},
},
},
meta: {
full: "NUM",
},
});
/*tslint:enable max-line-length*/
expect(data).to.eql(expectedScopedData);
});
});

// Regression test:
// https://github.com/FormidableLabs/inspectpack/issues/110
it("displays sizes correctly for scoped packages with null chunks", () => {
// Mutate stats data to replicate null chunk scenario.

// Add null asset chunk.
scopedInstance.stats.assets[0].chunks = [null].concat(
scopedInstance.stats.assets[0].chunks,
);

// Add null module chunks.
scopedInstance.stats.modules.forEach((mod) => {
if (mod.chunks) {
mod.chunks = [null, null, null].concat(mod.chunks);
}
});

return scopedInstance.template.json()
.then((dataStr) => {
// Inflate to real object and re-use previous test assertions.
const data = JSON.parse(normalizeOutput(JSON_PATH_RE, dataStr));

expect(data).to.eql(expectedScopedData);
});
});
});
Expand Down

0 comments on commit cddcb9a

Please sign in to comment.