88
99import Piscina from 'piscina' ;
1010import { ScriptTarget } from 'typescript' ;
11+ import type { Compiler , sources } from 'webpack' ;
1112import { maxWorkers } from '../../utils/environment-options' ;
1213
1314/**
@@ -74,7 +75,7 @@ export interface JavaScriptOptimizerOptions {
7475export class JavaScriptOptimizerPlugin {
7576 constructor ( public options : Partial < JavaScriptOptimizerOptions > = { } ) { }
7677
77- apply ( compiler : import ( 'webpack' ) . Compiler ) {
78+ apply ( compiler : Compiler ) {
7879 const { OriginalSource, SourceMapSource } = compiler . webpack . sources ;
7980
8081 compiler . hooks . compilation . tap ( PLUGIN_NAME , ( compilation ) => {
@@ -85,19 +86,43 @@ export class JavaScriptOptimizerPlugin {
8586 } ,
8687 async ( compilationAssets ) => {
8788 const scriptsToOptimize = [ ] ;
89+ const cache =
90+ compilation . options . cache && compilation . getCache ( 'JavaScriptOptimizerPlugin' ) ;
8891
8992 // Analyze the compilation assets for scripts that require optimization
9093 for ( const assetName of Object . keys ( compilationAssets ) ) {
91- if ( assetName . endsWith ( '.js' ) ) {
92- const scriptAsset = compilation . getAsset ( assetName ) ;
93- if ( scriptAsset && ! scriptAsset . info . minimized ) {
94- const { source, map } = scriptAsset . source . sourceAndMap ( ) ;
95- scriptsToOptimize . push ( {
96- name : scriptAsset . name ,
97- code : typeof source === 'string' ? source : source . toString ( ) ,
98- map,
99- } ) ;
94+ if ( ! assetName . endsWith ( '.js' ) ) {
95+ continue ;
96+ }
97+
98+ const scriptAsset = compilation . getAsset ( assetName ) ;
99+
100+ if ( scriptAsset && ! scriptAsset . info . minimized ) {
101+ const { source : scriptAssetSource , name } = scriptAsset ;
102+ let cacheItem ;
103+
104+ if ( cache ) {
105+ const eTag = cache . getLazyHashedEtag ( scriptAssetSource ) ;
106+ cacheItem = cache . getItemCache ( name , eTag ) ;
107+ const cachedOutput = await cacheItem . getPromise <
108+ { source : sources . Source } | undefined
109+ > ( ) ;
110+
111+ if ( cachedOutput ) {
112+ compilation . updateAsset ( name , cachedOutput . source , {
113+ minimized : true ,
114+ } ) ;
115+ continue ;
116+ }
100117 }
118+
119+ const { source, map } = scriptAssetSource . sourceAndMap ( ) ;
120+ scriptsToOptimize . push ( {
121+ name : scriptAsset . name ,
122+ code : typeof source === 'string' ? source : source . toString ( ) ,
123+ map,
124+ cacheItem,
125+ } ) ;
101126 }
102127 }
103128
@@ -154,7 +179,7 @@ export class JavaScriptOptimizerPlugin {
154179 // Enqueue script optimization tasks and update compilation assets as the tasks complete
155180 try {
156181 const tasks = [ ] ;
157- for ( const { name, code, map } of scriptsToOptimize ) {
182+ for ( const { name, code, map, cacheItem } of scriptsToOptimize ) {
158183 tasks . push (
159184 workerPool
160185 . run ( {
@@ -167,13 +192,14 @@ export class JavaScriptOptimizerPlugin {
167192 } )
168193 . then (
169194 ( { code, name, map } ) => {
170- let optimizedAsset ;
171- if ( map ) {
172- optimizedAsset = new SourceMapSource ( code , name , map ) ;
173- } else {
174- optimizedAsset = new OriginalSource ( code , name ) ;
175- }
195+ const optimizedAsset = map
196+ ? new SourceMapSource ( code , name , map )
197+ : new OriginalSource ( code , name ) ;
176198 compilation . updateAsset ( name , optimizedAsset , { minimized : true } ) ;
199+
200+ return cacheItem ?. storePromise ( {
201+ source : optimizedAsset ,
202+ } ) ;
177203 } ,
178204 ( error ) => {
179205 const optimizationError = new compiler . webpack . WebpackError (
0 commit comments