Skip to content

Commit

Permalink
Reduce the usage of lodash (#505)
Browse files Browse the repository at this point in the history
* Reduce the usage of lodash

* Add missing comment back

* Update unreleased changelog

* Add missing comment back

* Fix misplaced changelog

* Fix edge cases

* Fix viewer.js tests

* Make ESLint Happy
  • Loading branch information
SukkaW committed Aug 2, 2023
1 parent ff7631d commit e120231
Show file tree
Hide file tree
Showing 15 changed files with 44 additions and 46 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._

## UNRELEASED

* **Internal**
* Replace some lodash usages with JavaScript native API ([#505](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/505)) by [@sukkaw](https://github.com/sukkaw).

## 4.9.0

* **Improvement**
Expand Down
3 changes: 2 additions & 1 deletion client/components/ModuleItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ export default class ModuleItem extends PureComponent {
}

get invisibleHint() {
return `${_.upperFirst(this.itemType)} is not rendered in the treemap because it's too small.`;
const itemType = this.itemType.charAt(0).toUpperCase() + this.itemType.slice(1);
return `${itemType} is not rendered in the treemap because it's too small.`;
}

get isVisible() {
Expand Down
22 changes: 15 additions & 7 deletions src/analyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ function getViewerData(bundleStats, bundleDir, opts) {
const isAssetIncluded = createAssetsFilter(excludeAssets);

// Sometimes all the information is located in `children` array (e.g. problem in #10)
if (_.isEmpty(bundleStats.assets) && !_.isEmpty(bundleStats.children)) {
if (
(bundleStats.assets == null || bundleStats.assets.length === 0)
&& bundleStats.children && bundleStats.children.length > 0
) {
const {children} = bundleStats;
bundleStats = bundleStats.children[0];
// Sometimes if there are additional child chunks produced add them as child assets,
Expand All @@ -38,7 +41,7 @@ function getViewerData(bundleStats, bundleDir, opts) {
bundleStats.assets.push(asset);
});
}
} else if (!_.isEmpty(bundleStats.children)) {
} else if (bundleStats.children && bundleStats.children.length > 0) {
// Sometimes if there are additional child chunks produced add them as child assets
bundleStats.children.forEach((child) => {
child.assets.forEach((asset) => {
Expand All @@ -59,7 +62,7 @@ function getViewerData(bundleStats, bundleDir, opts) {
// See #22
asset.name = asset.name.replace(FILENAME_QUERY_REGEXP, '');

return FILENAME_EXTENSIONS.test(asset.name) && !_.isEmpty(asset.chunks) && isAssetIncluded(asset.name);
return FILENAME_EXTENSIONS.test(asset.name) && asset.chunks.length > 0 && isAssetIncluded(asset.name);
});

// Trying to parse bundle assets and get real module sizes if `bundleDir` is provided
Expand All @@ -82,11 +85,14 @@ function getViewerData(bundleStats, bundleDir, opts) {
continue;
}

bundlesSources[statAsset.name] = _.pick(bundleInfo, 'src', 'runtimeSrc');
bundlesSources[statAsset.name] = {
src: bundleInfo.src,
runtimeSrc: bundleInfo.runtimeSrc
};
Object.assign(parsedModules, bundleInfo.modules);
}

if (_.isEmpty(bundlesSources)) {
if (Object.keys(bundlesSources).length === 0) {
bundlesSources = null;
parsedModules = null;
logger.warn('\nNo bundles were parsed. Analyzer will show only original module sizes from stats file.\n');
Expand All @@ -97,8 +103,10 @@ function getViewerData(bundleStats, bundleDir, opts) {
// If asset is a childAsset, then calculate appropriate bundle modules by looking through stats.children
const assetBundles = statAsset.isChild ? getChildAssetBundles(bundleStats, statAsset.name) : bundleStats;
const modules = assetBundles ? getBundleModules(assetBundles) : [];
const asset = result[statAsset.name] = _.pick(statAsset, 'size');
const assetSources = bundlesSources && _.has(bundlesSources, statAsset.name) ?
const asset = result[statAsset.name] = {
size: statAsset.size
};
const assetSources = bundlesSources && Object.prototype.hasOwnProperty.call(bundlesSources, statAsset.name) ?
bundlesSources[statAsset.name] : null;

if (assetSources) {
Expand Down
11 changes: 4 additions & 7 deletions src/parseUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const fs = require('fs');
const _ = require('lodash');
const acorn = require('acorn');
const walk = require('acorn-walk');

Expand Down Expand Up @@ -140,14 +139,12 @@ function parseBundle(bundlePath) {
}
);

let modules;
const modules = {};

if (walkState.locations) {
modules = _.mapValues(walkState.locations,
loc => content.slice(loc.start, loc.end)
);
} else {
modules = {};
Object.entries(walkState.locations).forEach(([id, loc]) => {
modules[id] = content.slice(loc.start, loc.end);
});
}

return {
Expand Down
4 changes: 2 additions & 2 deletions src/tree/BaseFolder.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export default class BaseFolder extends Node {
}

get src() {
if (!_.has(this, '_src')) {
if (!Object.prototype.hasOwnProperty.call(this, '_src')) {
this._src = this.walk((node, src) => (src += node.src || ''), '', false);
}

return this._src;
}

get size() {
if (!_.has(this, '_size')) {
if (!Object.prototype.hasOwnProperty.call(this, '_size')) {
this._size = this.walk((node, size) => (size + node.size), 0, false);
}

Expand Down
3 changes: 1 addition & 2 deletions src/tree/ConcatenatedModule.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import _ from 'lodash';

import Module from './Module';
import ContentModule from './ContentModule';
import ContentFolder from './ContentFolder';
Expand Down Expand Up @@ -41,7 +40,7 @@ export default class ConcatenatedModule extends Module {
return;
}

const [folders, fileName] = [pathParts.slice(0, -1), _.last(pathParts)];
const [folders, fileName] = [pathParts.slice(0, -1), pathParts[pathParts.length - 1]];
let currentFolder = this;

folders.forEach(folderName => {
Expand Down
5 changes: 2 additions & 3 deletions src/tree/Folder.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import gzipSize from 'gzip-size';

import Module from './Module';
Expand All @@ -13,7 +12,7 @@ export default class Folder extends BaseFolder {
}

get gzipSize() {
if (!_.has(this, '_gzipSize')) {
if (!Object.prototype.hasOwnProperty.call(this, '_gzipSize')) {
this._gzipSize = this.src ? gzipSize.sync(this.src) : 0;
}

Expand All @@ -27,7 +26,7 @@ export default class Folder extends BaseFolder {
return;
}

const [folders, fileName] = [pathParts.slice(0, -1), _.last(pathParts)];
const [folders, fileName] = [pathParts.slice(0, -1), pathParts[pathParts.length - 1]];
let currentFolder = this;

folders.forEach(folderName => {
Expand Down
3 changes: 1 addition & 2 deletions src/tree/Module.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import gzipSize from 'gzip-size';

import Node from './Node';
Expand Down Expand Up @@ -40,7 +39,7 @@ export default class Module extends Node {
}

getGzipSize() {
if (!_.has(this, '_gzipSize')) {
if (!('_gzipSize' in this)) {
this._gzipSize = this.src ? gzipSize.sync(this.src) : undefined;
}

Expand Down
6 changes: 2 additions & 4 deletions src/tree/utils.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import _ from 'lodash';

const MULTI_MODULE_REGEXP = /^multi /u;

export function getModulePathParts(moduleData) {
if (MULTI_MODULE_REGEXP.test(moduleData.identifier)) {
return [moduleData.identifier];
}

const parsedPath = _
const loaders = moduleData.name.split('!');
// Removing loaders from module path: they're joined by `!` and the last part is a raw module path
.last(moduleData.name.split('!'))
const parsedPath = loaders[loaders.length - 1]
// Splitting module path into parts
.split('/')
// Removing first `.`
Expand Down
9 changes: 3 additions & 6 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
const {inspect, types} = require('util');
const _ = require('lodash');
const opener = require('opener');

const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

exports.createAssetsFilter = createAssetsFilter;

function createAssetsFilter(excludePatterns) {
const excludeFunctions = _(excludePatterns)
.castArray()
.compact()
const excludeFunctions = (Array.isArray(excludePatterns) ? excludePatterns : [excludePatterns])
.filter(Boolean)
.map(pattern => {
if (typeof pattern === 'string') {
pattern = new RegExp(pattern, 'u');
Expand All @@ -26,8 +24,7 @@ function createAssetsFilter(excludePatterns) {
}

return pattern;
})
.value();
});

if (excludeFunctions.length) {
return (asset) => excludeFunctions.every(fn => fn(asset) !== true);
Expand Down
2 changes: 1 addition & 1 deletion src/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function getChartData(analyzerOpts, ...args) {
chartData = null;
}

if (_.isPlainObject(chartData) && _.isEmpty(chartData)) {
if (_.isPlainObject(chartData) && Object.keys(chartData).length === 0) {
logger.error("Could't find any javascript bundles in provided stats file");
chartData = null;
}
Expand Down
11 changes: 5 additions & 6 deletions test/analyzer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const chai = require('chai');
chai.use(require('chai-subset'));
const {expect} = chai;
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const del = require('del');
Expand Down Expand Up @@ -107,7 +106,7 @@ describe('Analyzer', function () {
it('should gracefully parse invalid chunks', async function () {
generateReportFrom('with-invalid-chunk/stats.json');
const chartData = await getChartData();
const invalidChunk = _.find(chartData, {label: 'invalid-chunk.js'});
const invalidChunk = chartData.find(i => i.label === 'invalid-chunk.js');
expect(invalidChunk.groups).to.containSubset([
{
id: 1,
Expand All @@ -123,14 +122,14 @@ describe('Analyzer', function () {
it('should gracefully process missing chunks', async function () {
generateReportFrom('with-missing-chunk/stats.json');
const chartData = await getChartData();
const invalidChunk = _.find(chartData, {label: 'invalid-chunk.js'});
const invalidChunk = chartData.find(i => i.label === 'invalid-chunk.js');
expect(invalidChunk).to.exist;
expect(invalidChunk.statSize).to.equal(24);
forEachChartItem([invalidChunk], item => {
expect(typeof item.statSize).to.equal('number');
expect(item.parsedSize).to.be.undefined;
});
const validChunk = _.find(chartData, {label: 'valid-chunk.js'});
const validChunk = chartData.find(i => i.label === 'valid-chunk.js');
forEachChartItem([validChunk], item => {
expect(typeof item.statSize).to.equal('number');
expect(typeof item.parsedSize).to.equal('number');
Expand All @@ -140,14 +139,14 @@ describe('Analyzer', function () {
it('should gracefully process missing module chunks', async function () {
generateReportFrom('with-missing-module-chunks/stats.json');
const chartData = await getChartData();
const invalidChunk = _.find(chartData, {label: 'invalid-chunk.js'});
const invalidChunk = chartData.find(i => i.label === 'invalid-chunk.js');
expect(invalidChunk).to.exist;
expect(invalidChunk.statSize).to.equal(568);
forEachChartItem([invalidChunk], item => {
expect(typeof item.statSize).to.equal('number');
expect(item.parsedSize).to.be.undefined;
});
const validChunk = _.find(chartData, {label: 'valid-chunk.js'});
const validChunk = chartData.find(i => i.label === 'valid-chunk.js');
forEachChartItem([validChunk], item => {
expect(typeof item.statSize).to.equal('number');
expect(typeof item.parsedSize).to.equal('number');
Expand Down
2 changes: 1 addition & 1 deletion test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const getAvailableWebpackVersions = _.memoize(() =>
function forEachWebpackVersion(versions, cb) {
const availableVersions = getAvailableWebpackVersions();

if (_.isFunction(versions)) {
if (typeof versions === 'function') {
cb = versions;
versions = availableVersions;
} else {
Expand Down
3 changes: 1 addition & 2 deletions test/parseUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ chai.use(require('chai-subset'));
const {expect} = chai;
const fs = require('fs');

const _ = require('lodash');
const {parseBundle} = require('../lib/parseUtils');

const BUNDLES_DIR = `${__dirname}/bundles`;
Expand All @@ -17,7 +16,7 @@ describe('parseBundle', function () {
bundles
.filter(bundleName => bundleName.startsWith('valid'))
.forEach(bundleName => {
it(`should parse ${_.lowerCase(bundleName)}`, function () {
it(`should parse ${bundleName.toLocaleLowerCase()}`, function () {
const bundleFile = `${BUNDLES_DIR}/${bundleName}.js`;
const bundle = parseBundle(bundleFile);
const expectedModules = JSON.parse(fs.readFileSync(`${BUNDLES_DIR}/${bundleName}.modules.json`));
Expand Down
3 changes: 1 addition & 2 deletions test/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ chai.use(require('chai-subset'));
const {expect} = chai;
const fs = require('fs');
const del = require('del');
const _ = require('lodash');
const path = require('path');
const puppeteer = require('puppeteer');
const BundleAnalyzerPlugin = require('../lib/BundleAnalyzerPlugin');
Expand Down Expand Up @@ -113,7 +112,7 @@ describe('Plugin', function () {
await webpackCompile(config);

const chartData = await getChartDataFromReport();
expect(_.map(chartData, 'label'))
expect(chartData.map(i => i.label))
.to
.deep
.equal(['bundle.js']);
Expand Down

0 comments on commit e120231

Please sign in to comment.