11// @ts -check
2- /** @typedef {import("lodash.defaults") } defaults */
3- /** @typedef {import("lodash.assign") } assign */
42/** @typedef {import("webpack").Compiler } Compiler */
53/** @typedef {import("webpack").Stats } Stats */
64/** @typedef {import("webpack").compilation.Compilation } Compilation */
@@ -13,11 +11,6 @@ const path = require('path');
1311const fs = require ( 'fs' ) ;
1412const crypto = require ( 'crypto' ) ;
1513
16- const defaults = require ( 'lodash.defaults' ) ;
17- const assign = require ( 'lodash.assign' ) ;
18- const each = require ( 'lodash.foreach' ) ;
19- const fromPairs = require ( 'lodash.frompairs' ) ;
20- const toPairs = require ( 'lodash.topairs' ) ;
2114const stripAnsi = require ( './utils/stripAnsi' ) ;
2215
2316function getAssetPath ( compilation , name ) {
@@ -32,16 +25,19 @@ function getSource(compilation, name) {
3225/**
3326 * Merges the provided objects, ensuring that the resulting object has its properties in sorted order.
3427 * @template T
35- * @param {T } obj1
36- * @param {Partial<T> | undefined } obj2
37- * @returns {T }
28+ * @param {T } obj1 First object to merge.
29+ * @param {Partial<T> | undefined } obj2 Second object to merge, can be undefined.
30+ * @returns {* } A new object containing the merged properties of obj1 and obj2, with keys sorted.
3831 */
39- function mergeObjects ( obj1 , obj2 ) {
40- const mergedObj = assign ( { } , obj1 , obj2 ) ;
41- const sortedPairs = toPairs ( mergedObj ) . sort ( ( e1 , e2 ) => e1 [ 0 ] . localeCompare ( e2 [ 0 ] ) ) ;
42- // @ts -ignore: 2322 The Lodash typedefs aren't smart enough to be able to tell TS that we're
43- // regenerating the object from the original key-value pairs.
44- return fromPairs ( sortedPairs ) ;
32+ function mergeObjectsAndSortKeys ( obj1 , obj2 ) {
33+ const mergedObj = Object . assign ( { } , obj1 , obj2 ) ;
34+
35+ // Generates a new object with the same keys and values as mergedObj but in sorted order
36+ const sortedKeys = Object . keys ( mergedObj ) . sort ( ) ;
37+ return sortedKeys . reduce ( ( acc , key ) => {
38+ acc [ key ] = mergedObj [ key ] ;
39+ return acc ;
40+ } , { } ) ;
4541}
4642
4743class BundleTrackerPlugin {
@@ -70,17 +66,21 @@ class BundleTrackerPlugin {
7066 * @returns this
7167 */
7268 _setParamsFromCompiler ( compiler ) {
73- this . options = defaults ( { } , this . options , {
74- path : compiler . options . output ?. path ?? process . cwd ( ) ,
75- publicPath : compiler . options . output ?. publicPath ?? '' ,
76- filename : 'webpack-stats.json' ,
77- logTime : false ,
78- relativePath : false ,
79- integrity : false ,
80- indent : 2 ,
81- // https://www.w3.org/TR/SRI/#cryptographic-hash-functions
82- integrityHashes : [ 'sha256' , 'sha384' , 'sha512' ] ,
83- } ) ;
69+ this . options = Object . assign (
70+ { } ,
71+ {
72+ path : compiler . options . output ?. path ?? process . cwd ( ) ,
73+ publicPath : compiler . options . output ?. publicPath ?? '' ,
74+ filename : 'webpack-stats.json' ,
75+ logTime : false ,
76+ relativePath : false ,
77+ integrity : false ,
78+ indent : 2 ,
79+ // https://www.w3.org/TR/SRI/#cryptographic-hash-functions
80+ integrityHashes : [ 'sha256' , 'sha384' , 'sha512' ] ,
81+ } ,
82+ this . options ,
83+ ) ;
8484
8585 if ( this . options . filename ?. includes ( '/' ) ) {
8686 throw Error (
@@ -91,7 +91,9 @@ class BundleTrackerPlugin {
9191 }
9292
9393 // Set output directories
94- this . outputChunkDir = path . resolve ( compiler . options . output ?. path ?? process . cwd ( ) ) ;
94+ const outputPath = compiler . options . output ?. path ?? process . cwd ( ) ;
95+ this . outputChunkDir = path . resolve ( outputPath ) ;
96+
9597 // @ts -ignore: TS2345 this.options.path can't be undefined here because we set a default value above
9698 // @ts -ignore: TS2345 this.options.filename can't be undefined here because we set a default value above
9799 this . outputTrackerFile = path . resolve ( path . join ( this . options . path , this . options . filename ) ) ;
@@ -102,13 +104,13 @@ class BundleTrackerPlugin {
102104 /**
103105 * Write bundle tracker stats file
104106 *
105- * @param {Compiler } compiler
107+ * @param {Compiler } _compiler
106108 * @param {Partial<Contents> } contents
107109 */
108- _writeOutput ( compiler , contents ) {
109- assign ( this . contents , contents , {
110- assets : mergeObjects ( this . contents . assets , contents . assets ) ,
111- chunks : mergeObjects ( this . contents . chunks , contents . chunks ) ,
110+ _writeOutput ( _compiler , contents ) {
111+ Object . assign ( this . contents , contents , {
112+ assets : mergeObjectsAndSortKeys ( this . contents . assets , contents . assets ) ,
113+ chunks : mergeObjectsAndSortKeys ( this . contents . chunks , contents . chunks ) ,
112114 } ) ;
113115
114116 if ( this . options . publicPath ) {
@@ -159,7 +161,7 @@ class BundleTrackerPlugin {
159161 const error = findError ( stats . compilation ) ;
160162 this . _writeOutput ( compiler , {
161163 status : 'error' ,
162- error : error . name ?? 'unknown-error' ,
164+ error : error ? .name ?? 'unknown-error' ,
163165 message : stripAnsi ( error [ 'message' ] ) ,
164166 } ) ;
165167
@@ -168,7 +170,7 @@ class BundleTrackerPlugin {
168170
169171 /** @type {Contents } */
170172 const output = { status : 'done' , assets : { } , chunks : { } } ;
171- each ( stats . compilation . assets , ( file , assetName ) => {
173+ Object . entries ( stats . compilation . assets ) . map ( ( [ assetName , _ ] ) => {
172174 const fileInfo = {
173175 name : assetName ,
174176 path : getAssetPath ( stats . compilation , assetName ) ,
@@ -198,7 +200,7 @@ class BundleTrackerPlugin {
198200
199201 output . assets [ assetName ] = fileInfo ;
200202 } ) ;
201- each ( stats . compilation . chunkGroups , chunkGroup => {
203+ stats . compilation . chunkGroups . forEach ( chunkGroup => {
202204 if ( ! chunkGroup . isInitial ( ) ) return ;
203205
204206 output . chunks [ chunkGroup . name ] = chunkGroup . getFiles ( ) ;
0 commit comments