Skip to content

Commit

Permalink
Add compressionAlgorithm option
Browse files Browse the repository at this point in the history
  • Loading branch information
dcsaszar committed Apr 14, 2021
1 parent 4dfbb5c commit 80511a8
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 16 deletions.
17 changes: 10 additions & 7 deletions client/components/ModulesTreemap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import Search from './Search';
import {store} from '../store';
import ModulesList from './ModulesList';

const SIZE_SWITCH_ITEMS = [
{label: 'Stat', prop: 'statSize'},
{label: 'Parsed', prop: 'parsedSize'},
{label: 'Gzipped', prop: 'gzipSize'}
];
function allSizeSwitchItems() {
return [
{label: 'Stat', prop: 'statSize'},
{label: 'Parsed', prop: 'parsedSize'},
{label: window.compressedSizeLabel, prop: 'gzipSize'}
];
}

@observer
export default class ModulesTreemap extends Component {
Expand Down Expand Up @@ -138,7 +140,7 @@ export default class ModulesTreemap extends Component {
renderModuleSize(module, sizeType) {
const sizeProp = `${sizeType}Size`;
const size = module[sizeProp];
const sizeLabel = SIZE_SWITCH_ITEMS.find(item => item.prop === sizeProp).label;
const sizeLabel = allSizeSwitchItems().find(item => item.prop === sizeProp).label;
const isActive = (store.activeSize === sizeProp);

return (typeof size === 'number') ?
Expand All @@ -162,7 +164,8 @@ export default class ModulesTreemap extends Component {
};

@computed get sizeSwitchItems() {
return store.hasParsedSizes ? SIZE_SWITCH_ITEMS : SIZE_SWITCH_ITEMS.slice(0, 1);
const items = allSizeSwitchItems();
return store.hasParsedSizes ? items : items.slice(0, 1);
}

@computed get activeSizeItem() {
Expand Down
3 changes: 3 additions & 0 deletions src/BundleAnalyzerPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class BundleAnalyzerPlugin {
host: this.opts.analyzerHost,
port: this.opts.analyzerPort,
reportTitle: this.opts.reportTitle,
compressionAlgorithm: this.opts.compressionAlgorithm,
bundleDir: this.getBundleDirFromCompiler(),
logger: this.logger,
defaultSizes: this.opts.defaultSizes,
Expand All @@ -115,6 +116,7 @@ class BundleAnalyzerPlugin {
async generateJSONReport(stats) {
await viewer.generateJSONReport(stats, {
reportFilename: path.resolve(this.compiler.outputPath, this.opts.reportFilename || 'report.json'),
compressionAlgorithm: this.opts.compressionAlgorithm,
bundleDir: this.getBundleDirFromCompiler(),
logger: this.logger,
excludeAssets: this.opts.excludeAssets
Expand All @@ -126,6 +128,7 @@ class BundleAnalyzerPlugin {
openBrowser: this.opts.openAnalyzer,
reportFilename: path.resolve(this.compiler.outputPath, this.opts.reportFilename || 'report.html'),
reportTitle: this.opts.reportTitle,
compressionAlgorithm: this.opts.compressionAlgorithm,
bundleDir: this.getBundleDirFromCompiler(),
logger: this.logger,
defaultSizes: this.opts.defaultSizes,
Expand Down
12 changes: 10 additions & 2 deletions src/analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ const Logger = require('./Logger');
const Folder = require('./tree/Folder').default;
const {parseBundle} = require('./parseUtils');
const {createAssetsFilter} = require('./utils');
const {gzipSize} = require('./sizeUtils');
const {gzipSize, brotliSize} = require('./sizeUtils');

const FILENAME_QUERY_REGEXP = /\?.*$/u;
const FILENAME_EXTENSIONS = /\.(js|mjs)$/iu;

const COMPRESSED_SIZE = {
gzip: gzipSize,
brotli: brotliSize
};

module.exports = {
getViewerData,
readStatsFromFile
Expand All @@ -21,11 +26,14 @@ function getViewerData(bundleStats, bundleDir, opts) {
const {
logger = new Logger(),
excludeAssets = null,
compressedSize = gzipSize
compressionAlgorithm
} = opts || {};

const isAssetIncluded = createAssetsFilter(excludeAssets);

const compressedSize = COMPRESSED_SIZE[compressionAlgorithm];
if (!compressedSize) throw new Error(`Unsupported compression algorithm: ${compressionAlgorithm}.`);

// Sometimes all the information is located in `children` array (e.g. problem in #10)
if (_.isEmpty(bundleStats.assets) && !_.isEmpty(bundleStats.children)) {
const {children} = bundleStats;
Expand Down
17 changes: 16 additions & 1 deletion src/bin/analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const utils = require('../utils');
const SIZES = new Set(['stat', 'parsed', 'compressed']);
const ACCEPTED_SIZES = new Set([...SIZES, 'gzip']);

const ALGORITHMS = new Set(['gzip', 'brotli']);

const program = commander
.version(require('../../package.json').version)
.usage(
Expand Down Expand Up @@ -59,6 +61,12 @@ const program = commander
br(`Possible values: ${[...SIZES].join(', ')}`),
'parsed'
)
.option(
'--compression-algorithm <type>',
'Compression algorithm that will be used to calculate the compressed module sizes.' +
br(`Possible values: ${[...ALGORITHMS].join(', ')}`),
'gzip'
)
.option(
'-O, --no-open',
"Don't open report in default browser automatically."
Expand All @@ -84,6 +92,7 @@ let {
report: reportFilename,
title: reportTitle,
defaultSizes,
compressionAlgorithm,
logLevel,
open: openBrowser,
exclude: excludeAssets,
Expand All @@ -108,6 +117,9 @@ if (mode === 'server') {
if (!ACCEPTED_SIZES.has(defaultSizes)) {
showHelp(`Invalid default sizes option. Possible values are: ${[...SIZES].join(', ')}`);
}
if (!ALGORITHMS.has(compressionAlgorithm)) {
showHelp(`Invalid compression algorithm option. Possible values are: ${[...ALGORITHMS].join(', ')}`);
}

bundleStatsFile = resolve(bundleStatsFile);

Expand All @@ -128,6 +140,7 @@ if (mode === 'server') {
port,
host,
defaultSizes,
compressionAlgorithm,
reportTitle,
bundleDir,
excludeAssets,
Expand All @@ -139,13 +152,15 @@ if (mode === 'server') {
reportFilename: resolve(reportFilename || 'report.html'),
reportTitle,
defaultSizes,
compressionAlgorithm,
bundleDir,
excludeAssets,
logger: new Logger(logLevel)
});
} else if (mode === 'json') {
viewer.generateJSONReport(bundleStats, {
reportFilename: resolve(reportFilename || 'report.json'),
compressionAlgorithm,
bundleDir,
excludeAssets,
logger: new Logger(logLevel)
Expand All @@ -159,7 +174,7 @@ function showHelp(error) {
}

function br(str) {
return `\n${' '.repeat(28)}${str}`;
return `\n${' '.repeat(32)}${str}`;
}

function array() {
Expand Down
3 changes: 2 additions & 1 deletion 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, defaultSizes, mode} = {}) {
function renderViewer({title, enableWebSocket, chartData, defaultSizes, compressedSizeLabel, mode} = {}) {
return html`<!DOCTYPE html>
<html>
<head>
Expand All @@ -59,6 +59,7 @@ function renderViewer({title, enableWebSocket, chartData, defaultSizes, mode} =
<script>
window.chartData = ${escapeJson(chartData)};
window.defaultSizes = ${escapeJson(defaultSizes)};
window.compressedSizeLabel = ${escapeJson(compressedSizeLabel)};
</script>
</body>
</html>`;
Expand Down
19 changes: 14 additions & 5 deletions src/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ function resolveDefaultSizes(defaultSizes) {
return defaultSizes === 'compressed' ? 'gzip' : defaultSizes;
}

function resolveCompressedSizeLabel(compressionAlgorithm) {
return {gzip: 'Gzipped', brotli: 'Brotli'}[compressionAlgorithm];
}

module.exports = {
startServer,
generateReport,
Expand All @@ -43,10 +47,11 @@ async function startServer(bundleStats, opts) {
logger = new Logger(),
defaultSizes = 'parsed',
excludeAssets = null,
reportTitle
reportTitle,
compressionAlgorithm = 'gzip'
} = opts || {};

const analyzerOpts = {logger, excludeAssets};
const analyzerOpts = {logger, excludeAssets, compressionAlgorithm};

let chartData = getChartData(analyzerOpts, bundleStats, bundleDir);

Expand All @@ -64,6 +69,7 @@ async function startServer(bundleStats, opts) {
title: resolveTitle(reportTitle),
chartData,
defaultSizes: resolveDefaultSizes(defaultSizes),
compressedSizeLabel: resolveCompressedSizeLabel(compressionAlgorithm),
enableWebSocket: true
});
res.writeHead(200, {'Content-Type': 'text/html'});
Expand Down Expand Up @@ -130,13 +136,14 @@ async function generateReport(bundleStats, opts) {
openBrowser = true,
reportFilename,
reportTitle,
compressionAlgorithm = 'gzip',
bundleDir = null,
logger = new Logger(),
defaultSizes = 'parsed',
excludeAssets = null
} = opts || {};

const chartData = getChartData({logger, excludeAssets}, bundleStats, bundleDir);
const chartData = getChartData({logger, excludeAssets, compressionAlgorithm}, bundleStats, bundleDir);

if (!chartData) return;

Expand All @@ -145,6 +152,7 @@ async function generateReport(bundleStats, opts) {
title: resolveTitle(reportTitle),
chartData,
defaultSizes: resolveDefaultSizes(defaultSizes),
compressedSizeLabel: resolveCompressedSizeLabel(compressionAlgorithm),
enableWebSocket: false
});
const reportFilepath = path.resolve(bundleDir || process.cwd(), reportFilename);
Expand All @@ -160,9 +168,10 @@ async function generateReport(bundleStats, opts) {
}

async function generateJSONReport(bundleStats, opts) {
const {reportFilename, bundleDir = null, logger = new Logger(), excludeAssets = null} = opts || {};
const {reportFilename, bundleDir = null, logger = new Logger(), excludeAssets = null,
compressionAlgorithm = 'gzip'} = opts || {};

const chartData = getChartData({logger, excludeAssets}, bundleStats, bundleDir);
const chartData = getChartData({logger, excludeAssets, compressionAlgorithm}, bundleStats, bundleDir);

if (!chartData) return;

Expand Down
22 changes: 22 additions & 0 deletions test/analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,23 @@ describe('Analyzer', function () {
expect(generatedReportTitle).to.match(/^webpack-bundle-analyzer \[.* at \d{2}:\d{2}\]/u);
});
});

describe('compression algorithm', function () {
it('should accept --compression-algorithm brotli', async function () {
generateReportFrom('with-modules-chunk.json', '--compression-algorithm brotli');
expect(await getCompressedSizeLabel()).to.equal('Brotli');
});

it('should accept --compression-algorithm gzip', async function () {
generateReportFrom('with-modules-chunk.json', '--compression-algorithm gzip');
expect(await getCompressedSizeLabel()).to.equal('Gzipped');
});

it('should default to gzip', async function () {
generateReportFrom('with-modules-chunk.json');
expect(await getCompressedSizeLabel()).to.equal('Gzipped');
});
});
});
});

Expand All @@ -241,6 +258,11 @@ async function getChartData() {
return await nightmare.goto(`file://${__dirname}/output/report.html`).evaluate(() => window.chartData);
}

async function getCompressedSizeLabel() {
return await nightmare.goto(`file://${__dirname}/output/report.html`).evaluate(
() => window.compressedSizeLabel);
}

function forEachChartItem(chartData, cb) {
for (const item of chartData) {
cb(item);
Expand Down
39 changes: 39 additions & 0 deletions test/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,45 @@ describe('Plugin', function () {
expect(error).to.equal(reportTitleError);
});
});

describe('compressionAlgorithm', function () {
it('should default to gzip', async function () {
const config = makeWebpackConfig({
analyzerOpts: {}
});
await webpackCompile(config, '4.44.2');
await expectValidReport({
parsedSize: 1311,
gzipSize: 342
});
});

it('should support gzip', async function () {
const config = makeWebpackConfig({
analyzerOpts: {
compressionAlgorithm: 'gzip'
}
});
await webpackCompile(config, '4.44.2');
await expectValidReport({
parsedSize: 1311,
gzipSize: 342
});
});

it('should support brotli', async function () {
const config = makeWebpackConfig({
analyzerOpts: {
compressionAlgorithm: 'brotli'
}
});
await webpackCompile(config, '4.44.2');
await expectValidReport({
parsedSize: 1311,
gzipSize: 302
});
});
});
});

async function expectValidReport(opts) {
Expand Down

0 comments on commit 80511a8

Please sign in to comment.