@@ -37,8 +37,58 @@ class CopyPlugin {
37
37
this . options = options . options || { } ;
38
38
}
39
39
40
+ static async createSnapshot ( compilation , startTime , dependency ) {
41
+ if ( ! compilation . fileSystemInfo ) {
42
+ return ;
43
+ }
44
+
45
+ // eslint-disable-next-line consistent-return
46
+ return new Promise ( ( resolve , reject ) => {
47
+ compilation . fileSystemInfo . createSnapshot (
48
+ startTime ,
49
+ [ dependency ] ,
50
+ // eslint-disable-next-line no-undefined
51
+ undefined ,
52
+ // eslint-disable-next-line no-undefined
53
+ undefined ,
54
+ null ,
55
+ ( error , snapshot ) => {
56
+ if ( error ) {
57
+ reject ( error ) ;
58
+
59
+ return ;
60
+ }
61
+
62
+ resolve ( snapshot ) ;
63
+ }
64
+ ) ;
65
+ } ) ;
66
+ }
67
+
68
+ static async checkSnapshotValid ( compilation , snapshot ) {
69
+ if ( ! compilation . fileSystemInfo ) {
70
+ return ;
71
+ }
72
+
73
+ // eslint-disable-next-line consistent-return
74
+ return new Promise ( ( resolve , reject ) => {
75
+ compilation . fileSystemInfo . checkSnapshotValid (
76
+ snapshot ,
77
+ ( error , isValid ) => {
78
+ if ( error ) {
79
+ reject ( error ) ;
80
+
81
+ return ;
82
+ }
83
+
84
+ resolve ( isValid ) ;
85
+ }
86
+ ) ;
87
+ } ) ;
88
+ }
89
+
40
90
// eslint-disable-next-line class-methods-use-this
41
- async runPattern ( compiler , compilation , logger , inputPattern ) {
91
+ static async runPattern ( compiler , compilation , logger , cache , inputPattern ) {
42
92
const pattern =
43
93
typeof inputPattern === 'string'
44
94
? { from : inputPattern }
@@ -49,7 +99,6 @@ class CopyPlugin {
49
99
pattern . to = path . normalize (
50
100
typeof pattern . to !== 'undefined' ? pattern . to : ''
51
101
) ;
52
-
53
102
pattern . context = path . normalize (
54
103
typeof pattern . context !== 'undefined'
55
104
? ! path . isAbsolute ( pattern . context )
@@ -266,64 +315,109 @@ class CopyPlugin {
266
315
compilation . fileDependencies . add ( file . absoluteFrom ) ;
267
316
}
268
317
269
- logger . debug ( `reading " ${ file . absoluteFrom } " to write to assets` ) ;
318
+ let source ;
270
319
271
- let data ;
320
+ if ( cache ) {
321
+ const cacheEntry = await cache . getPromise ( file . relativeFrom , null ) ;
272
322
273
- try {
274
- data = await readFile ( inputFileSystem , file . absoluteFrom ) ;
275
- } catch ( error ) {
276
- compilation . errors . push ( error ) ;
323
+ if ( cacheEntry ) {
324
+ const isValidSnapshot = await CopyPlugin . checkSnapshotValid (
325
+ compilation ,
326
+ cacheEntry . snapshot
327
+ ) ;
277
328
278
- return ;
329
+ if ( isValidSnapshot ) {
330
+ ( { source } = cacheEntry ) ;
331
+ }
332
+ }
279
333
}
280
334
281
- if ( pattern . transform ) {
282
- logger . log ( `transforming content for "${ file . absoluteFrom } "` ) ;
283
-
284
- if ( pattern . cacheTransform ) {
285
- const cacheDirectory = pattern . cacheTransform . directory
286
- ? pattern . cacheTransform . directory
287
- : typeof pattern . cacheTransform === 'string'
288
- ? pattern . cacheTransform
289
- : findCacheDir ( { name : 'copy-webpack-plugin' } ) || os . tmpdir ( ) ;
290
- let defaultCacheKeys = {
291
- version,
292
- transform : pattern . transform ,
293
- contentHash : crypto . createHash ( 'md4' ) . update ( data ) . digest ( 'hex' ) ,
294
- } ;
295
-
296
- if ( typeof pattern . cacheTransform . keys === 'function' ) {
297
- defaultCacheKeys = await pattern . cacheTransform . keys (
298
- defaultCacheKeys ,
299
- file . absoluteFrom
300
- ) ;
301
- } else {
302
- defaultCacheKeys = {
303
- ...defaultCacheKeys ,
304
- ...pattern . cacheTransform . keys ,
335
+ if ( ! source ) {
336
+ let startTime ;
337
+
338
+ if ( cache ) {
339
+ startTime = Date . now ( ) ;
340
+ }
341
+
342
+ logger . debug ( `reading "${ file . absoluteFrom } " to write to assets` ) ;
343
+
344
+ let data ;
345
+
346
+ try {
347
+ data = await readFile ( inputFileSystem , file . absoluteFrom ) ;
348
+ } catch ( error ) {
349
+ compilation . errors . push ( error ) ;
350
+
351
+ return ;
352
+ }
353
+
354
+ if ( pattern . transform ) {
355
+ logger . log ( `transforming content for "${ file . absoluteFrom } "` ) ;
356
+
357
+ if ( pattern . cacheTransform ) {
358
+ const cacheDirectory = pattern . cacheTransform . directory
359
+ ? pattern . cacheTransform . directory
360
+ : typeof pattern . cacheTransform === 'string'
361
+ ? pattern . cacheTransform
362
+ : findCacheDir ( { name : 'copy-webpack-plugin' } ) || os . tmpdir ( ) ;
363
+ let defaultCacheKeys = {
364
+ version,
365
+ transform : pattern . transform ,
366
+ contentHash : crypto
367
+ . createHash ( 'md4' )
368
+ . update ( data )
369
+ . digest ( 'hex' ) ,
305
370
} ;
306
- }
307
371
308
- const cacheKeys = serialize ( defaultCacheKeys ) ;
372
+ if ( typeof pattern . cacheTransform . keys === 'function' ) {
373
+ defaultCacheKeys = await pattern . cacheTransform . keys (
374
+ defaultCacheKeys ,
375
+ file . absoluteFrom
376
+ ) ;
377
+ } else {
378
+ defaultCacheKeys = {
379
+ ...defaultCacheKeys ,
380
+ ...pattern . cacheTransform . keys ,
381
+ } ;
382
+ }
309
383
310
- try {
311
- const result = await cacache . get ( cacheDirectory , cacheKeys ) ;
384
+ const cacheKeys = serialize ( defaultCacheKeys ) ;
312
385
313
- logger . debug (
314
- `getting cached transformation for "${ file . absoluteFrom } "`
315
- ) ;
386
+ try {
387
+ const result = await cacache . get ( cacheDirectory , cacheKeys ) ;
316
388
317
- ( { data } = result ) ;
318
- } catch ( _ignoreError ) {
319
- data = await pattern . transform ( data , file . absoluteFrom ) ;
389
+ logger . debug (
390
+ `getting cached transformation for " ${ file . absoluteFrom } "`
391
+ ) ;
320
392
321
- logger . debug ( `caching transformation for "${ file . absoluteFrom } "` ) ;
393
+ ( { data } = result ) ;
394
+ } catch ( _ignoreError ) {
395
+ data = await pattern . transform ( data , file . absoluteFrom ) ;
396
+
397
+ logger . debug (
398
+ `caching transformation for "${ file . absoluteFrom } "`
399
+ ) ;
322
400
323
- await cacache . put ( cacheDirectory , cacheKeys , data ) ;
401
+ await cacache . put ( cacheDirectory , cacheKeys , data ) ;
402
+ }
403
+ } else {
404
+ data = await pattern . transform ( data , file . absoluteFrom ) ;
324
405
}
325
- } else {
326
- data = await pattern . transform ( data , file . absoluteFrom ) ;
406
+ }
407
+
408
+ source = new RawSource ( data ) ;
409
+
410
+ if ( cache ) {
411
+ const snapshot = await CopyPlugin . createSnapshot (
412
+ compilation ,
413
+ startTime ,
414
+ file . relativeFrom
415
+ ) ;
416
+
417
+ await cache . storePromise ( file . relativeFrom , null , {
418
+ source,
419
+ snapshot,
420
+ } ) ;
327
421
}
328
422
}
329
423
@@ -349,7 +443,7 @@ class CopyPlugin {
349
443
{ resourcePath : file . absoluteFrom } ,
350
444
file . webpackTo ,
351
445
{
352
- content : data ,
446
+ content : source . source ( ) ,
353
447
context : pattern . context ,
354
448
}
355
449
) ;
@@ -374,7 +468,7 @@ class CopyPlugin {
374
468
}
375
469
376
470
// eslint-disable-next-line no-param-reassign
377
- file . data = data ;
471
+ file . source = source ;
378
472
// eslint-disable-next-line no-param-reassign
379
473
file . targetPath = normalizePath ( file . webpackTo ) ;
380
474
// eslint-disable-next-line no-param-reassign
@@ -392,6 +486,10 @@ class CopyPlugin {
392
486
393
487
compiler . hooks . thisCompilation . tap ( pluginName , ( compilation ) => {
394
488
const logger = compilation . getLogger ( 'copy-webpack-plugin' ) ;
489
+ const cache = compilation . getCache
490
+ ? compilation . getCache ( 'CopyWebpackPlugin' )
491
+ : // eslint-disable-next-line no-undefined
492
+ undefined ;
395
493
396
494
compilation . hooks . additionalAssets . tapAsync (
397
495
'copy-webpack-plugin' ,
@@ -404,7 +502,13 @@ class CopyPlugin {
404
502
assets = await Promise . all (
405
503
this . patterns . map ( ( item ) =>
406
504
limit ( async ( ) =>
407
- this . runPattern ( compiler , compilation , logger , item )
505
+ CopyPlugin . runPattern (
506
+ compiler ,
507
+ compilation ,
508
+ logger ,
509
+ cache ,
510
+ item
511
+ )
408
512
)
409
513
)
410
514
) ;
@@ -426,12 +530,10 @@ class CopyPlugin {
426
530
absoluteFrom,
427
531
targetPath,
428
532
webpackTo,
429
- data ,
533
+ source ,
430
534
force,
431
535
} = asset ;
432
536
433
- const source = new RawSource ( data ) ;
434
-
435
537
// For old version webpack 4
436
538
/* istanbul ignore if */
437
539
if ( typeof compilation . emitAsset !== 'function' ) {
0 commit comments