Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): improve fidelity and performance …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
clydin authored and filipesilva committed Oct 6, 2021
1 parent c9b26c4 commit f10a828
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
15 changes: 12 additions & 3 deletions packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts
Expand Up @@ -7,9 +7,7 @@
*/

declare module 'babel-loader' {
type BabelLoaderCustomizer<T> = (
babel: typeof import('@babel/core'),
) => {
type BabelLoaderCustomizer<T> = (babel: typeof import('@babel/core')) => {
customOptions?(
this: import('webpack').loader.LoaderContext,
loaderOptions: Record<string, unknown>,
Expand All @@ -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<T>(customizer: BabelLoaderCustomizer<T>): import('webpack').loader.Loader;
}
25 changes: 22 additions & 3 deletions packages/angular_devkit/build_angular/src/babel/webpack-loader.ts
Expand Up @@ -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';
Expand All @@ -21,6 +22,9 @@ interface AngularCustomOptions extends Pick<ApplicationPresetOptions, 'angularLi
};
}

// Extract Sourcemap input type from the remapping function since it is not currently exported
type SourceMapInput = Exclude<Parameters<typeof remapping>[0], unknown[]>;

/**
* Cached instance of the compiler-cli linker's needsLinking function.
*/
Expand Down Expand Up @@ -201,10 +205,10 @@ export default custom<AngularCustomOptions>(() => {

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 || []),
Expand All @@ -229,5 +233,20 @@ export default custom<AngularCustomOptions>(() => {
],
};
},
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;
},
};
});

0 comments on commit f10a828

Please sign in to comment.