From e7ec0346e69c090ded7d9ec6d3574deb79926db0 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 5 Aug 2021 10:28:20 -0400 Subject: [PATCH] fix(@angular-devkit/build-angular): avoid attempting to optimize copied JavaScript assets When in watch mode (`ng serve`/`ng build --watch`), Webpack's `copy-webpack-plugin` is currently used to implement the project `assets` option within `angular.json`. Files specified by the `assets` option are intended to be copied to the output unmodified and in their original form. However, if any JavaScript assets were present they previously would have been unintentionally subject to their respective optimization plugins which would result in modified asset outputs and the potential for breakage of the assets. `ng build` outside of watch mode uses a direct file copy with copy-on-write (where supported) to process assets and is therefore not affected by this situation. When the `copy-webpack-plugin` is used, it adds a `copied` flag to an asset's info metadata. This flag is now used to exclude all such copied JavaScript assets from optimization. (cherry picked from commit f5d019f9d6ad6d8fdea37836564d9ee190deb23c) --- .../plugins/javascript-optimizer-plugin.ts | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts b/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts index c861dd6636e1..0e7c4ba4ef59 100644 --- a/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts +++ b/packages/angular_devkit/build_angular/src/webpack/plugins/javascript-optimizer-plugin.ts @@ -96,34 +96,36 @@ export class JavaScriptOptimizerPlugin { } const scriptAsset = compilation.getAsset(assetName); + // Skip assets that have already been optimized or are verbatim copies (project assets) + if (!scriptAsset || scriptAsset.info.minimized || scriptAsset.info.copied) { + continue; + } - if (scriptAsset && !scriptAsset.info.minimized) { - const { source: scriptAssetSource, name } = scriptAsset; - let cacheItem; - - if (cache) { - const eTag = cache.getLazyHashedEtag(scriptAssetSource); - cacheItem = cache.getItemCache(name, eTag); - const cachedOutput = await cacheItem.getPromise< - { source: sources.Source } | undefined - >(); - - if (cachedOutput) { - compilation.updateAsset(name, cachedOutput.source, { - minimized: true, - }); - continue; - } + const { source: scriptAssetSource, name } = scriptAsset; + let cacheItem; + + if (cache) { + const eTag = cache.getLazyHashedEtag(scriptAssetSource); + cacheItem = cache.getItemCache(name, eTag); + const cachedOutput = await cacheItem.getPromise< + { source: sources.Source } | undefined + >(); + + if (cachedOutput) { + compilation.updateAsset(name, cachedOutput.source, { + minimized: true, + }); + continue; } - - const { source, map } = scriptAssetSource.sourceAndMap(); - scriptsToOptimize.push({ - name: scriptAsset.name, - code: typeof source === 'string' ? source : source.toString(), - map, - cacheItem, - }); } + + const { source, map } = scriptAssetSource.sourceAndMap(); + scriptsToOptimize.push({ + name: scriptAsset.name, + code: typeof source === 'string' ? source : source.toString(), + map, + cacheItem, + }); } if (scriptsToOptimize.length === 0) {