Skip to content

Commit

Permalink
Combine entrypoint to chunk data in chartData
Browse files Browse the repository at this point in the history
  • Loading branch information
pas-trop-de-zele committed Aug 15, 2022
1 parent 165ba49 commit 5679ca9
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 97 deletions.
23 changes: 2 additions & 21 deletions client/components/Dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ export default class Dropdown extends PureComponent {

constructor(props) {
super(props);
this.state = {
selectedOption: DEFAULT_DROPDOWN_SELECTION
};
}

render() {
Expand All @@ -24,7 +21,7 @@ export default class Dropdown extends PureComponent {
{label}:
</div>
<div>
<select className={s.select} name={label} id={label} onChange={this.handleSelection}>
<select className={s.select} id={label} name={label} onChange={this.handleSelection}>
<DropdownOption value={DEFAULT_DROPDOWN_SELECTION}/>
{options.map(option =>
<DropdownOption value={option}/>
Expand All @@ -43,22 +40,6 @@ export default class Dropdown extends PureComponent {
return;
}

this.setState({selectedOption: selected}, () => {
store.selectedChunks = [];
for (const chunk of store.allChunks) {
if (store.entrypointsToChunksMap[this.state.selectedOption].has(chunk.label)) {
store.selectedChunks.push(chunk);
}
}
});

// this.setState({selectedOption: selected}, () => {
// store.selectedChunks = [];
// for (const chunk of store.allChunks) {
// if (chunk.label in store.entrypointsToChunksMap[this.state.selectedOption]) {
// store.selectedChunks.push(chunk);
// }
// }
// });
store.selectedChunks = store.allChunks.filter(chunk => chunk.isInitialByEntrypoint[selected] ?? false);
}
}
6 changes: 1 addition & 5 deletions client/components/ModulesTreemap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default class ModulesTreemap extends Component {
</div>
<div className={s.sidebarGroup}>
<Dropdown label="Filter to initial chunks"
options={this.entrypoints}/>
options={store.entrypoints}/>
</div>
<div className={s.sidebarGroup}>
<Search label="Search modules"
Expand Down Expand Up @@ -166,10 +166,6 @@ export default class ModulesTreemap extends Component {
];
};

@computed get entrypoints() {
return Object.keys(store.entrypointsToChunksMap);
}

@computed get sizeSwitchItems() {
return store.hasParsedSizes ? SIZE_SWITCH_ITEMS : SIZE_SWITCH_ITEMS.slice(0, 1);
}
Expand Down
12 changes: 2 additions & 10 deletions client/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,8 @@ export class Store {
this.selectedChunks = this.allChunks;
}
setEntrypoints(_entrypointsToChunksMap) {
// this.entrypointsToChunksMap = {};
// Object.entries(entrypointsToChunksMap).forEach(([entrypoint, chunkList]) => {
// this.entrypointsToChunksMap[entrypoint] = new Set(chunkList);
// });
this.entrypointsToChunksMap = Object.entries(_entrypointsToChunksMap).reduce((entrypointsToChunksMap, [entrypoint, chunks]) => {
entrypointsToChunksMap[entrypoint] = new Set(chunks);
return entrypointsToChunksMap;
}, {});
setEntrypoints(entrypoints) {
this.entrypoints = entrypoints;
}
@computed get hasParsedSizes() {
Expand Down
2 changes: 1 addition & 1 deletion client/viewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ try {
window.addEventListener('load', () => {
store.defaultSize = `${window.defaultSizes}Size`;
store.setModules(window.chartData);
store.setEntrypoints(window.entrypointsToChunksMap);
store.setEntrypoints(window.entrypoints);
render(
<ModulesTreemap/>,
document.getElementById('app')
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"scripts": {
"start": "gulp watch",
"build": "gulp build",
"buildAndStart": "gulp build ; cd ../nucleus/packages/$BUNDLE ; pnpm bundle:build ; cd ../../../webpack-bundle-analyzer",
"buildAndStart": "gulp build && test -n '${BUNDLE}' && cd ../nucleus/packages/$BUNDLE && pnpm bundle:build && cd ../../../webpack-bundle-analyzer",
"npm-publish": "npm run lint && npm run build && npm test && npm publish",
"lint": "eslint --ext js,jsx .",
"install-test-webpack-versions": "./bin/install-test-webpack-versions.sh",
Expand Down
19 changes: 18 additions & 1 deletion src/analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const FILENAME_QUERY_REGEXP = /\?.*$/u;
const FILENAME_EXTENSIONS = /\.(js|mjs)$/iu;

module.exports = {
getChunkToInitialByEntrypoint,
getViewerData,
readStatsFromFile
};
Expand Down Expand Up @@ -147,6 +148,7 @@ function getViewerData(bundleStats, bundleDir, opts) {
return result;
}, {});

const chunkToInitialByEntrypoint = getChunkToInitialByEntrypoint(bundleStats);
return Object.entries(assets).map(([filename, asset]) => ({
label: filename,
isAsset: true,
Expand All @@ -157,7 +159,8 @@ function getViewerData(bundleStats, bundleDir, opts) {
statSize: asset.tree.size || asset.size,
parsedSize: asset.parsedSize,
gzipSize: asset.gzipSize,
groups: _.invokeMap(asset.tree.children, 'toChartData')
groups: _.invokeMap(asset.tree.children, 'toChartData'),
isInitialByEntrypoint: chunkToInitialByEntrypoint[filename] ?? {}
}));
}

Expand Down Expand Up @@ -211,3 +214,17 @@ function createModulesTree(modules) {

return root;
}

function getChunkToInitialByEntrypoint(bundleStats) {
if (bundleStats === null || bundleStats === undefined) {
return {};
}
const chunkToEntrypointInititalMap = {};
Object.values(bundleStats.entrypoints || {}).forEach((entrypoint) => {
for (const asset of entrypoint.assets) {
chunkToEntrypointInititalMap[asset.name] = chunkToEntrypointInititalMap[asset.name] ?? {};
chunkToEntrypointInititalMap[asset.name][entrypoint.name] = true;
}
});
return chunkToEntrypointInititalMap;
};
6 changes: 3 additions & 3 deletions src/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function getScript(filename, mode) {
}
}

function renderViewer({title, enableWebSocket, chartData, entrypointsToChunksMap, defaultSizes, mode} = {}) {
function renderViewer({title, enableWebSocket, chartData, entrypoints, defaultSizes, mode} = {}) {
return html`<!DOCTYPE html>
<html>
<head>
Expand All @@ -58,9 +58,9 @@ function renderViewer({title, enableWebSocket, chartData, entrypointsToChunksMap
<div id="app"></div>
<script>
window.chartData = ${escapeJson(chartData)};
window.entrypointsToChunksMap = ${escapeJson(entrypointsToChunksMap)};
window.entrypoints = ${escapeJson(entrypoints)};
window.defaultSizes = ${escapeJson(defaultSizes)};
</script>
</body>
</html>`;
}
}
5 changes: 0 additions & 5 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,4 @@ exports.open = function (uri, logger) {
} catch (err) {
logger.debug(`Opener failed to open "${uri}":\n${err}`);
}
};

exports.isJsFile = function (fileName) {
const JS_REGEX = /\.js$/u;
return JS_REGEX.test(fileName);
};
31 changes: 10 additions & 21 deletions src/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const {bold} = require('chalk');

const Logger = require('./Logger');
const analyzer = require('./analyzer');
const {isJsFile, open} = require('./utils');
const {open} = require('./utils');
const {renderViewer} = require('./template');

const projectRoot = path.resolve(__dirname, '..');
Expand All @@ -26,7 +26,7 @@ module.exports = {
startServer,
generateReport,
generateJSONReport,
getEntrypointsToChunksMap,
getEntrypoints,
// deprecated
start: startServer
};
Expand All @@ -46,9 +46,9 @@ async function startServer(bundleStats, opts) {
const analyzerOpts = {logger, excludeAssets};

let chartData = getChartData(analyzerOpts, bundleStats, bundleDir);
const entrypointsToChunksMap = getEntrypointsToChunksMap(bundleStats);
const entrypoints = getEntrypoints(bundleStats);

if (!chartData || !entrypointsToChunksMap) return;
if (!chartData) return;

const sirvMiddleware = sirv(`${projectRoot}/public`, {
// disables caching and traverse the file system on every request
Expand All @@ -61,7 +61,7 @@ async function startServer(bundleStats, opts) {
mode: 'server',
title: resolveTitle(reportTitle),
chartData,
entrypointsToChunksMap,
entrypoints,
defaultSizes,
enableWebSocket: true
});
Expand Down Expand Up @@ -136,15 +136,15 @@ async function generateReport(bundleStats, opts) {
} = opts || {};

const chartData = getChartData({logger, excludeAssets}, bundleStats, bundleDir);
const entrypointsToChunksMap = getEntrypointsToChunksMap(bundleStats);
const entrypoints = getEntrypoints(bundleStats);

if (!chartData) return;

const reportHtml = renderViewer({
mode: 'static',
title: resolveTitle(reportTitle),
chartData,
entrypointsToChunksMap,
entrypoints,
defaultSizes,
enableWebSocket: false
});
Expand Down Expand Up @@ -193,20 +193,9 @@ function getChartData(analyzerOpts, ...args) {
return chartData;
}

function getEntrypointsToChunksMap(bundleStats) {
function getEntrypoints(bundleStats) {
if (bundleStats === null || bundleStats === undefined) {
return {};
return [];
}

return Object.values(bundleStats.entrypoints || {}).reduce((entrypointsToChunksMap, entrypoint) => {
if (!(entrypoint.name in entrypointsToChunksMap)) {
entrypointsToChunksMap[entrypoint.name] = [];
}
entrypoint.assets.forEach(asset => {
if (isJsFile(asset.name)) {
entrypointsToChunksMap[entrypoint.name].push(asset.name);
}
});
return entrypointsToChunksMap;
}, {});
return Object.values(bundleStats.entrypoints || {}).map(entrypoint => entrypoint.name);
}
50 changes: 50 additions & 0 deletions test/analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const path = require('path');
const del = require('del');
const childProcess = require('child_process');
const puppeteer = require('puppeteer');
const {getChunkToInitialByEntrypoint} = require('../src/analyzer');

let browser;

Expand Down Expand Up @@ -225,6 +226,55 @@ describe('Analyzer', function () {
});
});


describe('getChunkToInitialByEntrypoint', function () {
it('should map chunks correctly to entrypoints', function () {
const bundleStats = {
entrypoints: {
'A': {
name: 'A',
assets: [
{
name: 'chunkA.js'
}
]
},
'B': {
name: 'B',
assets: [
{
name: 'chunkA.js'
},
{
name: 'chunkB.js'
}
]
}
}
};
expect(JSON.stringify(getChunkToInitialByEntrypoint(bundleStats))).to.equal(JSON.stringify({
'chunkA.js': {'A': true, 'B': true},
'chunkB.js': {'B': true}
}));
});

it('should handle when bundlestats is null or undefined ', function () {
expect(JSON.stringify(getChunkToInitialByEntrypoint(null))).to.equal(JSON.stringify({}));
expect(JSON.stringify(getChunkToInitialByEntrypoint(undefined))).to.equal(JSON.stringify({}));
});

it('should handle when bundlestats is emoty', function () {
const bundleStatsWithoutEntryPoints = {};
expect(JSON.stringify(getChunkToInitialByEntrypoint(bundleStatsWithoutEntryPoints))).to.equal(JSON.stringify({}));
});

it('should handle when entrypoints is empty', function () {
const bundleStatsEmptyEntryPoint = {entrypoints: {}};
expect(JSON.stringify(getChunkToInitialByEntrypoint(bundleStatsEmptyEntryPoint))).to.equal(JSON.stringify({}));
});

});

function generateJSONReportFrom(statsFilename) {
childProcess.execSync(`../lib/bin/analyzer.js -m json -r output/report.json stats/${statsFilename}`, {
cwd: __dirname
Expand Down
15 changes: 1 addition & 14 deletions test/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const chai = require('chai');
chai.use(require('chai-subset'));
const {expect} = chai;
const {createAssetsFilter, isJsFile} = require('../lib/utils');
const {createAssetsFilter} = require('../lib/utils');

describe('createAssetsFilter', function () {

Expand Down Expand Up @@ -56,17 +56,4 @@ describe('createAssetsFilter', function () {
expect(filter('bar-foo')).to.equal(true);
});

});

describe('isJsFile', function () {
it('should recognize .js files', function () {
expect(isJsFile('file.js')).to.equal(true);
expect(isJsFile('file.ts')).to.equal(false);
expect(isJsFile('file.css')).to.equal(false);
});

it('should filter out .js files', function () {
const DUMMY_FILES = ['file.js', 'file.css', 'file.ts'];
expect(DUMMY_FILES.filter(isJsFile).join()).to.equal(['file.js'].join());
});
});
Loading

0 comments on commit 5679ca9

Please sign in to comment.