@@ -2,6 +2,7 @@ const fs = require("node:fs");
22const path = require ( "node:path" ) ;
33const url = require ( "node:url" ) ;
44const puppeteer = require ( "puppeteer" ) ;
5+ const webpack = require ( "webpack" ) ;
56const BundleAnalyzerPlugin = require ( "../lib/BundleAnalyzerPlugin" ) ;
67const { isZstdSupported } = require ( "../src/sizeUtils" ) ;
78const {
@@ -95,26 +96,29 @@ describe("Plugin", () => {
9596 recursive : true ,
9697 } ) ;
9798 } ) ;
99+ const NODE_MAJOR = Number . parseInt ( process . versions . node . split ( "." ) [ 0 ] , 10 ) ;
100+ const SKIP_WEBPACK_4 = NODE_MAJOR >= 20 ;
98101
99- forEachWebpackVersion ( [ "4.44.2" ] , ( { it , webpackCompile } ) => {
100- // Webpack 5 doesn't support `jsonpFunction` option
101- it ( "should support webpack config with custom `jsonpFunction` name" , async ( ) => {
102- const config = makeWebpackConfig ( {
103- multipleChunks : true ,
104- } ) ;
102+ if ( ! SKIP_WEBPACK_4 ) {
103+ forEachWebpackVersion ( [ "4.44.2" ] , ( { it , webpackCompile } ) => {
104+ it ( "should support webpack config with custom `jsonpFunction` name" , async ( ) => {
105+ const config = makeWebpackConfig ( {
106+ multipleChunks : true ,
107+ } ) ;
105108
106- config . output . jsonpFunction = "somethingCompletelyDifferent" ;
109+ config . output . jsonpFunction = "somethingCompletelyDifferent" ;
107110
108- await webpackCompile ( config ) ;
111+ await webpackCompile ( config ) ;
109112
110- await expectValidReport ( {
111- parsedSize : 1349 ,
112- gzipSize : 358 ,
113+ await expectValidReport ( {
114+ parsedSize : 1349 ,
115+ gzipSize : 358 ,
116+ } ) ;
113117 } ) ;
114118 } ) ;
115- } ) ;
119+ }
116120
117- /* eslint jest/no-standalone-expect: ["error", { additionalTestBlockFunctions: ["forEachWebpackVersion"] }] */
121+ /* eslint jest/no-standalone-expect: ["error", { additionalTestBlockFunctions: ["forEachWebpackVersion", "runTest" ] }] */
118122 forEachWebpackVersion ( ( { it, webpackCompile } ) => {
119123 it ( "should allow to generate json report" , async ( ) => {
120124 const config = makeWebpackConfig ( {
@@ -182,7 +186,8 @@ describe("Plugin", () => {
182186 } ) ;
183187
184188 describe ( "reportTitle" , ( ) => {
185- it ( "should have a sensible default" , async ( ) => {
189+ const runTest = SKIP_WEBPACK_4 ? it . skip : it ;
190+ runTest ( "should have a sensible default" , async ( ) => {
186191 const config = makeWebpackConfig ( ) ;
187192 await webpackCompile ( config , "4.44.2" ) ;
188193 const generatedReportTitle = await getTitleFromReport ( ) ;
@@ -191,7 +196,7 @@ describe("Plugin", () => {
191196 ) ;
192197 } ) ;
193198
194- it ( "should support a string value" , async ( ) => {
199+ runTest ( "should support a string value" , async ( ) => {
195200 const reportTitle = "A string report title" ;
196201 const config = makeWebpackConfig ( {
197202 analyzerOpts : {
@@ -203,7 +208,7 @@ describe("Plugin", () => {
203208 expect ( generatedReportTitle ) . toBe ( reportTitle ) ;
204209 } ) ;
205210
206- it ( "should support a function value" , async ( ) => {
211+ runTest ( "should support a function value" , async ( ) => {
207212 const reportTitleResult = "A string report title" ;
208213 const config = makeWebpackConfig ( {
209214 analyzerOpts : {
@@ -215,7 +220,7 @@ describe("Plugin", () => {
215220 expect ( generatedReportTitle ) . toBe ( reportTitleResult ) ;
216221 } ) ;
217222
218- it ( "should propagate an error in a function " , async ( ) => {
223+ runTest ( "should log an error when reportTitle throws " , async ( ) => {
219224 const reportTitleError = new Error ( "test" ) ;
220225 const config = makeWebpackConfig ( {
221226 analyzerOpts : {
@@ -225,33 +230,36 @@ describe("Plugin", () => {
225230 } ,
226231 } ) ;
227232
228- let error = null ;
229- try {
230- await webpackCompile ( config , "4.44.2" ) ;
231- } catch ( err ) {
232- error = err ;
233- }
233+ const errorSpy = jest
234+ . spyOn ( console , "error" )
235+ . mockImplementation ( ( ) => { } ) ;
236+ await webpackCompile ( config , "4.44.2" ) ;
234237
235- expect ( error ) . toBe ( reportTitleError ) ;
238+ expect ( errorSpy ) . toHaveBeenCalledWith (
239+ expect . stringContaining ( "action failed: test" ) ,
240+ ) ;
241+
242+ errorSpy . mockRestore ( ) ;
236243 } ) ;
237244 } ) ;
238245
239246 describe ( "compressionAlgorithm" , ( ) => {
240- it ( "should default to gzip" , async ( ) => {
247+ const runTest = SKIP_WEBPACK_4 ? it . skip : it ;
248+ runTest ( "should default to gzip" , async ( ) => {
241249 const config = makeWebpackConfig ( { analyzerOpts : { } } ) ;
242250 await webpackCompile ( config , "4.44.2" ) ;
243251 await expectValidReport ( { parsedSize : 1317 , gzipSize : 341 } ) ;
244252 } ) ;
245253
246- it ( "should support gzip" , async ( ) => {
254+ runTest ( "should support gzip" , async ( ) => {
247255 const config = makeWebpackConfig ( {
248256 analyzerOpts : { compressionAlgorithm : "gzip" } ,
249257 } ) ;
250258 await webpackCompile ( config , "4.44.2" ) ;
251259 await expectValidReport ( { parsedSize : 1317 , gzipSize : 341 } ) ;
252260 } ) ;
253261
254- it ( "should support brotli" , async ( ) => {
262+ runTest ( "should support brotli" , async ( ) => {
255263 const config = makeWebpackConfig ( {
256264 analyzerOpts : { compressionAlgorithm : "brotli" } ,
257265 } ) ;
@@ -264,7 +272,7 @@ describe("Plugin", () => {
264272 } ) ;
265273
266274 if ( isZstdSupported ) {
267- it ( "should support zstd" , async ( ) => {
275+ runTest ( "should support zstd" , async ( ) => {
268276 const config = makeWebpackConfig ( {
269277 analyzerOpts : { compressionAlgorithm : "zstd" } ,
270278 } ) ;
@@ -279,4 +287,40 @@ describe("Plugin", () => {
279287 }
280288 } ) ;
281289 } ) ;
290+ describe ( "Issue #499" , ( ) => {
291+ it ( "should not cause WebpackLogger 'done hook' error when callback throws" , ( done ) => {
292+ expect . assertions ( 1 ) ;
293+
294+ const compiler = webpack ( {
295+ mode : "development" ,
296+ entry : __filename ,
297+ plugins : [ new BundleAnalyzerPlugin ( { analyzerMode : "disabled" } ) ] ,
298+ } ) ;
299+
300+ let webpackLoggerError = false ;
301+ const originalConsoleError = console . error ;
302+
303+ console . error = ( ...args ) => {
304+ const message = args . join ( " " ) ;
305+ if ( message . includes ( "No such label 'done hook'" ) ) {
306+ webpackLoggerError = true ;
307+ }
308+ originalConsoleError . apply ( console , args ) ;
309+ } ;
310+
311+ compiler . run ( ( ) => {
312+ try {
313+ throw new Error ( "Intentional test error" ) ;
314+ } catch {
315+ // Swallow expected error
316+ }
317+ } ) ;
318+
319+ setTimeout ( ( ) => {
320+ console . error = originalConsoleError ;
321+ expect ( webpackLoggerError ) . toBe ( false ) ;
322+ done ( ) ;
323+ } , 1000 ) ;
324+ } ) ;
325+ } ) ;
282326} ) ;
0 commit comments