From 2fca17ae51492b2cc2c0bee3e5adc566006103fd Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Thu, 15 May 2025 18:03:48 -0300 Subject: [PATCH 01/12] Removed lodash.get and lodash.topairs + Optimized sorting of objects keys --- lib/index.js | 38 ++++++++++++++++++-------------------- package.json | 6 +----- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/lib/index.js b/lib/index.js index 4e4c2d4..7a84a89 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,5 @@ // @ts-check /** @typedef {import("lodash.defaults")} defaults */ -/** @typedef {import("lodash.assign")} assign */ -/** @typedef {import("lodash.get")} get */ /** @typedef {import("webpack").Compiler} Compiler */ /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").compilation.Compilation} Compilation */ @@ -15,11 +13,7 @@ const fs = require('fs'); const crypto = require('crypto'); const defaults = require('lodash.defaults'); -const assign = require('lodash.assign'); -const get = require('lodash.get'); const each = require('lodash.foreach'); -const fromPairs = require('lodash.frompairs'); -const toPairs = require('lodash.topairs'); const stripAnsi = require('./utils/stripAnsi'); function getAssetPath(compilation, name) { @@ -36,14 +30,17 @@ function getSource(compilation, name) { * @template T * @param {T} obj1 * @param {Partial | undefined} obj2 - * @returns {T} + * @returns {*} */ -function mergeObjects(obj1, obj2) { - const mergedObj = assign({}, obj1, obj2); - const sortedPairs = toPairs(mergedObj).sort((e1, e2) => e1[0].localeCompare(e2[0])); - // @ts-ignore: 2322 The Lodash typedefs aren't smart enough to be able to tell TS that we're - // regenerating the object from the original key-value pairs. - return fromPairs(sortedPairs); +function mergeObjectsAndSortKeys(obj1, obj2) { + const mergedObj = Object.assign({}, obj1, obj2); + + // Generates a new object with the same keys and values as mergedObj but in sorted order + const sortedKeys = Object.keys(mergedObj).sort(); + return sortedKeys.reduce((acc, key) => { + acc[key] = mergedObj[key]; + return acc; + }, {}); } class BundleTrackerPlugin { @@ -73,8 +70,8 @@ class BundleTrackerPlugin { */ _setParamsFromCompiler(compiler) { this.options = defaults({}, this.options, { - path: get(compiler.options, 'output.path', process.cwd()), - publicPath: get(compiler.options, 'output.publicPath', ''), + path: compiler.options.output?.path ?? process.cwd(), + publicPath: compiler.options.output?.publicPath ?? '', filename: 'webpack-stats.json', logTime: false, relativePath: false, @@ -93,7 +90,8 @@ class BundleTrackerPlugin { } // Set output directories - this.outputChunkDir = path.resolve(get(compiler.options, 'output.path', process.cwd())); + const outputPath = compiler.options.output?.path ?? process.cwd(); + this.outputChunkDir = path.resolve(outputPath); // @ts-ignore: TS2345 this.options.path can't be undefined here because we set a default value above // @ts-ignore: TS2345 this.options.filename can't be undefined here because we set a default value above this.outputTrackerFile = path.resolve(path.join(this.options.path, this.options.filename)); @@ -108,9 +106,9 @@ class BundleTrackerPlugin { * @param {Partial} contents */ _writeOutput(compiler, contents) { - assign(this.contents, contents, { - assets: mergeObjects(this.contents.assets, contents.assets), - chunks: mergeObjects(this.contents.chunks, contents.chunks), + Object.assign(this.contents, contents, { + assets: mergeObjectsAndSortKeys(this.contents.assets, contents.assets), + chunks: mergeObjectsAndSortKeys(this.contents.chunks, contents.chunks), }); if (this.options.publicPath) { @@ -161,7 +159,7 @@ class BundleTrackerPlugin { const error = findError(stats.compilation); this._writeOutput(compiler, { status: 'error', - error: get(error, 'name', 'unknown-error'), + error: error?.name ? error.name : 'unknown-error', message: stripAnsi(error['message']), }); diff --git a/package.json b/package.json index 7f8118f..77405c4 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,7 @@ "lodash.assign": "^4.2.0", "lodash.defaults": "^4.2.0", "lodash.foreach": "^4.5.0", - "lodash.frompairs": "^4.0.1", - "lodash.get": "^4.4.2", - "lodash.topairs": "^4.3.0" + "lodash.frompairs": "^4.0.1" }, "devDependencies": { "@types/babel__traverse": "7.0.6", @@ -53,8 +51,6 @@ "@types/lodash.defaults": "^4.2.7", "@types/lodash.foreach": "^4.5.7", "@types/lodash.frompairs": "^4.0.7", - "@types/lodash.get": "^4.4.7", - "@types/lodash.topairs": "^4.3.7", "@types/node": "^13.13.52", "@types/webpack": "^4.41.33", "@typescript-eslint/eslint-plugin": "^2.34.0", From 3470a8f1bb58d2f7ef334d811b6b10802fe1e492 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Thu, 15 May 2025 18:05:17 -0300 Subject: [PATCH 02/12] Removed lodash.defaults --- lib/index.js | 4 +--- package.json | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/index.js b/lib/index.js index 7a84a89..45d1b5a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,4 @@ // @ts-check -/** @typedef {import("lodash.defaults")} defaults */ /** @typedef {import("webpack").Compiler} Compiler */ /** @typedef {import("webpack").Stats} Stats */ /** @typedef {import("webpack").compilation.Compilation} Compilation */ @@ -12,7 +11,6 @@ const path = require('path'); const fs = require('fs'); const crypto = require('crypto'); -const defaults = require('lodash.defaults'); const each = require('lodash.foreach'); const stripAnsi = require('./utils/stripAnsi'); @@ -69,7 +67,7 @@ class BundleTrackerPlugin { * @returns this */ _setParamsFromCompiler(compiler) { - this.options = defaults({}, this.options, { + this.options = Object.assign({}, this.options, { path: compiler.options.output?.path ?? process.cwd(), publicPath: compiler.options.output?.publicPath ?? '', filename: 'webpack-stats.json', diff --git a/package.json b/package.json index 77405c4..2eb55d3 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ }, "dependencies": { "lodash.assign": "^4.2.0", - "lodash.defaults": "^4.2.0", "lodash.foreach": "^4.5.0", "lodash.frompairs": "^4.0.1" }, @@ -48,7 +47,6 @@ "@types/babel__traverse": "7.0.6", "@types/lodash": "4.14.173", "@types/lodash.assign": "^4.2.7", - "@types/lodash.defaults": "^4.2.7", "@types/lodash.foreach": "^4.5.7", "@types/lodash.frompairs": "^4.0.7", "@types/node": "^13.13.52", From efd2fb1f09d1b1b4ab7fdb1d1d43355e3612dace Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Thu, 15 May 2025 18:08:04 -0300 Subject: [PATCH 03/12] Removed lodash.assign --- lib/index.js | 2 +- package.json | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/index.js b/lib/index.js index 45d1b5a..3be2632 100644 --- a/lib/index.js +++ b/lib/index.js @@ -104,7 +104,7 @@ class BundleTrackerPlugin { * @param {Partial} contents */ _writeOutput(compiler, contents) { - Object.assign(this.contents, contents, { + Object.assign({}, this.contents, contents, { assets: mergeObjectsAndSortKeys(this.contents.assets, contents.assets), chunks: mergeObjectsAndSortKeys(this.contents.chunks, contents.chunks), }); diff --git a/package.json b/package.json index 2eb55d3..ed5871f 100644 --- a/package.json +++ b/package.json @@ -39,14 +39,12 @@ ] }, "dependencies": { - "lodash.assign": "^4.2.0", "lodash.foreach": "^4.5.0", "lodash.frompairs": "^4.0.1" }, "devDependencies": { "@types/babel__traverse": "7.0.6", "@types/lodash": "4.14.173", - "@types/lodash.assign": "^4.2.7", "@types/lodash.foreach": "^4.5.7", "@types/lodash.frompairs": "^4.0.7", "@types/node": "^13.13.52", From fd2b8648ea1d8b72315593aca7aa3da831387393 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Thu, 15 May 2025 18:11:43 -0300 Subject: [PATCH 04/12] Removed last lodash functions --- lib/index.js | 7 +++---- package.json | 7 ------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/index.js b/lib/index.js index 3be2632..7774862 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,7 +11,6 @@ const path = require('path'); const fs = require('fs'); const crypto = require('crypto'); -const each = require('lodash.foreach'); const stripAnsi = require('./utils/stripAnsi'); function getAssetPath(compilation, name) { @@ -100,10 +99,10 @@ class BundleTrackerPlugin { /** * Write bundle tracker stats file * - * @param {Compiler} compiler + * @param {Compiler} _compiler * @param {Partial} contents */ - _writeOutput(compiler, contents) { + _writeOutput(_compiler, contents) { Object.assign({}, this.contents, contents, { assets: mergeObjectsAndSortKeys(this.contents.assets, contents.assets), chunks: mergeObjectsAndSortKeys(this.contents.chunks, contents.chunks), @@ -196,7 +195,7 @@ class BundleTrackerPlugin { output.assets[assetName] = fileInfo; }); - each(stats.compilation.chunkGroups, chunkGroup => { + stats.compilation.chunkGroups.forEach(chunkGroup => { if (!chunkGroup.isInitial()) return; output.chunks[chunkGroup.name] = chunkGroup.getFiles(); diff --git a/package.json b/package.json index ed5871f..54da40e 100644 --- a/package.json +++ b/package.json @@ -38,15 +38,8 @@ "jest-extended" ] }, - "dependencies": { - "lodash.foreach": "^4.5.0", - "lodash.frompairs": "^4.0.1" - }, "devDependencies": { "@types/babel__traverse": "7.0.6", - "@types/lodash": "4.14.173", - "@types/lodash.foreach": "^4.5.7", - "@types/lodash.frompairs": "^4.0.7", "@types/node": "^13.13.52", "@types/webpack": "^4.41.33", "@typescript-eslint/eslint-plugin": "^2.34.0", From 50abe190fbb694de38cfe525bfc38f2d3049da94 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Thu, 15 May 2025 18:39:41 -0300 Subject: [PATCH 05/12] Removed some lodash functions + Fixed little bug with undefined each function --- lib/index.js | 2 +- tests/base.test.js | 5 ++--- tests/fixtures/commons.js | 4 +--- tests/webpack5.test.js | 5 ++--- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/index.js b/lib/index.js index 7774862..50726a0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -165,7 +165,7 @@ class BundleTrackerPlugin { /** @type {Contents} */ const output = { status: 'done', assets: {}, chunks: {} }; - each(stats.compilation.assets, (file, assetName) => { + Object.entries(stats.compilation.assets).map(([_, assetName]) => { const fileInfo = { name: assetName, path: getAssetPath(stats.compilation, assetName), diff --git a/tests/base.test.js b/tests/base.test.js index bfc7f27..0ed9c4b 100644 --- a/tests/base.test.js +++ b/tests/base.test.js @@ -2,7 +2,6 @@ 'use strict'; const fs = require('fs'); -const toPairs = require('lodash.topairs'); const zlib = require('zlib'); const path = require('path'); const rimraf = require('rimraf'); @@ -761,8 +760,8 @@ describe('BundleTrackerPlugin bases tests', () => { () => { const statsStr = fs.readFileSync(path.join(OUTPUT_DIR, 'webpack-stats.json'), 'utf8'); const stats = JSON.parse(statsStr); - const assetsKeys = toPairs(stats.assets).map(pair => pair[0]); - const chunksKeys = toPairs(stats.chunks).map(pair => pair[0]); + const assetsKeys = Object.entries(stats.assets).map(pair => pair[0]); + const chunksKeys = Object.entries(stats.chunks).map(pair => pair[0]); expect(assetsKeys).toEqual(['css/appA.css', 'js/1.js', 'js/appA.js', 'js/appZ.js', 'js/commons.js']); expect(chunksKeys).toEqual(['appA', 'appZ']); diff --git a/tests/fixtures/commons.js b/tests/fixtures/commons.js index 9485d2c..713af83 100644 --- a/tests/fixtures/commons.js +++ b/tests/fixtures/commons.js @@ -1,9 +1,7 @@ 'use strict'; -const assign = require('lodash.assign'); - const output = { name: '' }; -assign(output, { name: 'common' }); +Object.assign({}, output, { name: 'common' }); module.exports = output; diff --git a/tests/webpack5.test.js b/tests/webpack5.test.js index e4870a0..3c1fe3b 100644 --- a/tests/webpack5.test.js +++ b/tests/webpack5.test.js @@ -2,7 +2,6 @@ 'use strict'; const fs = require('fs'); -const toPairs = require('lodash.topairs'); const zlib = require('zlib'); const path = require('path'); const rimraf = require('rimraf'); @@ -807,8 +806,8 @@ describe('BundleTrackerPlugin bases tests', () => { () => { const statsStr = fs.readFileSync(path.join(OUTPUT_DIR, 'webpack-stats.json'), 'utf8'); const stats = JSON.parse(statsStr); - const assetsKeys = toPairs(stats.assets).map(pair => pair[0]); - const chunksKeys = toPairs(stats.chunks).map(pair => pair[0]); + const assetsKeys = Object.entries(stats.assets).map(pair => pair[0]); + const chunksKeys = Object.entries(stats.chunks).map(pair => pair[0]); expect(assetsKeys).toEqual(['css/appA.css', 'js/75.js', 'js/appA.js', 'js/appZ.js', 'js/commons.js']); expect(chunksKeys).toEqual(['appA', 'appZ']); From b87a87e48e50898f70b1f7f02531bff5cc38936e Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 12:49:46 -0300 Subject: [PATCH 06/12] Fixed order in Object.entries --- lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 50726a0..6673d6d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -165,7 +165,7 @@ class BundleTrackerPlugin { /** @type {Contents} */ const output = { status: 'done', assets: {}, chunks: {} }; - Object.entries(stats.compilation.assets).map(([_, assetName]) => { + Object.entries(stats.compilation.assets).map(([assetName, _]) => { const fileInfo = { name: assetName, path: getAssetPath(stats.compilation, assetName), From 7efffc79f88ac72e3608736736a5e486730d55f0 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 12:50:05 -0300 Subject: [PATCH 07/12] Added cross-env to allow testing in Windows --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 54da40e..f48eb59 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,11 @@ "pretty": "prettier --loglevel warn --write lib/*.js tests/*.js", "pretty-lint": "prettier --check lib/*.js tests/*.js", "pretest": "npm run pretty-lint", - "test": "NODE_OPTIONS=--openssl-legacy-provider jest --runInBand --env node", - "test-debug": "NODE_OPTIONS=--openssl-legacy-provider node --inspect-brk=0.0.0.0 node_modules/jest/bin/jest --runInBand --env node", + "test": "cross-env NODE_OPTIONS=--openssl-legacy-provider jest --runInBand --env node", + "test-debug": "cross-env NODE_OPTIONS=--openssl-legacy-provider node --inspect-brk=0.0.0.0 node_modules/jest/bin/jest --runInBand --env node", "posttest": "tsc", "test-watch": "jest --runInBand --env node --watchAll", - "ci": "NODE_OPTIONS=--openssl-legacy-provider npm run pretest && jest --runInBand --coverage --env node && npm run posttest" + "ci": "cross-env NODE_OPTIONS=--openssl-legacy-provider npm run pretest && jest --runInBand --coverage --env node && npm run posttest" }, "jest": { "setupFilesAfterEnv": [ @@ -46,6 +46,7 @@ "@typescript-eslint/parser": "^2.34.0", "commitizen": "^4.3.0", "compression-webpack-plugin": "^6.1.1", + "cross-env": "^7.0.3", "css-loader": "^5.2.7", "cz-conventional-changelog": "3.3.0", "eslint": "^6.8.0", From aca6a7d77b2eb2b0f267fe1f27a2f8aea76a57eb Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 13:13:20 -0300 Subject: [PATCH 08/12] Added missing docs for mergeObjectsAndSortKeys --- lib/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/index.js b/lib/index.js index 6673d6d..cc3322b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -25,9 +25,9 @@ function getSource(compilation, name) { /** * Merges the provided objects, ensuring that the resulting object has its properties in sorted order. * @template T - * @param {T} obj1 - * @param {Partial | undefined} obj2 - * @returns {*} + * @param {T} obj1 First object to merge. + * @param {Partial | undefined} obj2 Second object to merge, can be undefined. + * @returns {*} A new object containing the merged properties of obj1 and obj2, with keys sorted. */ function mergeObjectsAndSortKeys(obj1, obj2) { const mergedObj = Object.assign({}, obj1, obj2); From dc7236111d110549928ad0077922931884a3f016 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 13:17:37 -0300 Subject: [PATCH 09/12] Merge branch 'master' into remove-lodash-optimizations --- lib/index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index cc3322b..230ff25 100644 --- a/lib/index.js +++ b/lib/index.js @@ -156,7 +156,7 @@ class BundleTrackerPlugin { const error = findError(stats.compilation); this._writeOutput(compiler, { status: 'error', - error: error?.name ? error.name : 'unknown-error', + error: error?.name ?? 'unknown-error', message: stripAnsi(error['message']), }); diff --git a/package.json b/package.json index f48eb59..f2eec14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webpack-bundle-tracker", - "version": "3.1.1", + "version": "3.2.0", "description": "Spits out some stats about webpack compilation process to a file", "keywords": [ "bundle", From 0510ec380151714297c0c1e2b46722db63dad130 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 13:56:45 -0300 Subject: [PATCH 10/12] Fix assign --- lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 230ff25..ed1894b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -103,7 +103,7 @@ class BundleTrackerPlugin { * @param {Partial} contents */ _writeOutput(_compiler, contents) { - Object.assign({}, this.contents, contents, { + Object.assign(this.contents, contents, { assets: mergeObjectsAndSortKeys(this.contents.assets, contents.assets), chunks: mergeObjectsAndSortKeys(this.contents.chunks, contents.chunks), }); From df8cda294f983278f78d539604b31cd814622921 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 13:57:05 -0300 Subject: [PATCH 11/12] Removed blank line --- lib/utils/stripAnsi.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/utils/stripAnsi.js b/lib/utils/stripAnsi.js index a301b8c..a11ad99 100644 --- a/lib/utils/stripAnsi.js +++ b/lib/utils/stripAnsi.js @@ -2,7 +2,6 @@ * This code is based on the strip-ansi library by Chalk. * Source: https://github.com/chalk/strip-ansi */ - function ansiRegex({ onlyFirst = false } = {}) { const pattern = [ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', From ed14165356f17b28746e9c4c12638833868e3345 Mon Sep 17 00:00:00 2001 From: Genaro Camele Date: Sat, 31 May 2025 15:00:49 -0300 Subject: [PATCH 12/12] Fixed issues with Object.assign --- lib/index.js | 26 +++++++++++++++----------- tests/fixtures/commons.js | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/index.js b/lib/index.js index ed1894b..fe14a93 100644 --- a/lib/index.js +++ b/lib/index.js @@ -66,17 +66,21 @@ class BundleTrackerPlugin { * @returns this */ _setParamsFromCompiler(compiler) { - this.options = Object.assign({}, this.options, { - path: compiler.options.output?.path ?? process.cwd(), - publicPath: compiler.options.output?.publicPath ?? '', - filename: 'webpack-stats.json', - logTime: false, - relativePath: false, - integrity: false, - indent: 2, - // https://www.w3.org/TR/SRI/#cryptographic-hash-functions - integrityHashes: ['sha256', 'sha384', 'sha512'], - }); + this.options = Object.assign( + {}, + { + path: compiler.options.output?.path ?? process.cwd(), + publicPath: compiler.options.output?.publicPath ?? '', + filename: 'webpack-stats.json', + logTime: false, + relativePath: false, + integrity: false, + indent: 2, + // https://www.w3.org/TR/SRI/#cryptographic-hash-functions + integrityHashes: ['sha256', 'sha384', 'sha512'], + }, + this.options, + ); if (this.options.filename?.includes('/')) { throw Error( diff --git a/tests/fixtures/commons.js b/tests/fixtures/commons.js index 713af83..f13dd3d 100644 --- a/tests/fixtures/commons.js +++ b/tests/fixtures/commons.js @@ -2,6 +2,6 @@ const output = { name: '' }; -Object.assign({}, output, { name: 'common' }); +Object.assign(output, { name: 'common' }); module.exports = output;