From 196c838bf2d80baba998cfcc84eec69642c6304b Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 17 Feb 2021 10:59:57 -0500 Subject: [PATCH] fix(@angular-devkit/build-angular): improve fidelity and performance of babel loader sourcemaps This change uses the `@ampproject/remapping` package to merge sourcemaps generated from the customized babel loader used to perform the partial compilation linking in applications as well as other optimization and downleveling transformations. This provides more accurate output mapppings as well as improved performance and lower memory usage when source maps are enabled within a build. --- .../build_angular/src/babel/babel-loader.d.ts | 15 ++++++++--- .../build_angular/src/babel/webpack-loader.ts | 25 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts b/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts index 0c0756d9e54a..49fbff8b8344 100644 --- a/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts +++ b/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts @@ -7,9 +7,7 @@ */ declare module 'babel-loader' { - type BabelLoaderCustomizer = ( - babel: typeof import('@babel/core'), - ) => { + type BabelLoaderCustomizer = (babel: typeof import('@babel/core')) => { customOptions?( this: import('webpack').loader.LoaderContext, loaderOptions: Record, @@ -20,6 +18,17 @@ declare module 'babel-loader' { configuration: import('@babel/core').PartialConfig, loaderArguments: { source: string; map?: unknown; customOptions: T }, ): import('@babel/core').TransformOptions; + result?( + this: import('webpack').loader.LoaderContext, + result: import('@babel/core').BabelFileResult, + context: { + source: string; + map?: unknown; + customOptions: T; + configuration: import('@babel/core').PartialConfig; + options: import('@babel/core').TransformOptions; + }, + ): import('@babel/core').BabelFileResult; }; function custom(customizer: BabelLoaderCustomizer): import('webpack').loader.Loader; } diff --git a/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts b/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts index 04fd3d0f7fb7..b41bd7f6d7a5 100644 --- a/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts +++ b/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ +import remapping from '@ampproject/remapping'; import { custom } from 'babel-loader'; import { ScriptTarget } from 'typescript'; import { loadEsmModule } from '../utils/load-esm'; @@ -21,6 +22,9 @@ interface AngularCustomOptions extends Pick[0], unknown[]>; + /** * Cached instance of the compiler-cli linker's needsLinking function. */ @@ -201,10 +205,10 @@ export default custom(() => { return { ...configuration.options, - // Workaround for https://github.com/babel/babel-loader/pull/896 is available - // Delete once the above PR is released + // Using `false` disables babel from attempting to locate sourcemaps or process any inline maps. + // The babel types do not include the false option even though it is valid // eslint-disable-next-line @typescript-eslint/no-explicit-any - inputSourceMap: configuration.options.inputSourceMap || (false as any), // Typings are not correct + inputSourceMap: false as any, plugins, presets: [ ...(configuration.options.presets || []), @@ -229,5 +233,20 @@ export default custom(() => { ], }; }, + result(result, { map: inputSourceMap }) { + if (result.map && inputSourceMap) { + // Merge the intermediate sourcemap generated by babel with the input source map. + // The casting is required due to slight differences in the types for babel and + // `@ampproject/remapping` source map objects but both are compatible with Webpack. + // This method for merging is used because it provides more accurate output + // and is faster while using less memory. + result.map = remapping( + [result.map as SourceMapInput, inputSourceMap as SourceMapInput], + () => null, + ) as typeof result.map; + } + + return result; + }, }; });