Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[12.2.x] fix(@angular-devkit/build-angular): improve fidelity and performance of babel loader sourcemaps #21900

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 12 additions & 3 deletions packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import remapping from '@ampproject/remapping';
import { needsLinking } from '@angular/compiler-cli/linker';
import { custom } from 'babel-loader';
import { ScriptTarget } from 'typescript';
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[]>;

function requiresLinking(path: string, source: string): boolean {
// @angular/core and @angular/compiler will cause false positives
// Also, TypeScript files do not require linking
Expand Down Expand Up @@ -146,10 +150,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 @@ -174,5 +178,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;
},
};
});