fix(ngcc): do not inline source-maps for non-inline typings source-maps (#37363)

Inline source-maps in typings files can impact IDE performance
so ngcc should only add such maps if the original typings file
contains inline source-maps.

Fixes #37324

PR Close #37363
This commit is contained in:
Pete Bacon Darwin 2020-05-30 20:49:44 +01:00 committed by Matias Niemelä
parent c3651cec0b
commit b45f336635
3 changed files with 72 additions and 2 deletions

View File

@ -42,8 +42,16 @@ export function renderSourceAndMap(
const rawMergedMap: RawSourceMap = generatedFile.renderFlattenedSourceMap();
const mergedMap = fromObject(rawMergedMap);
if (generatedFile.sources[0]?.inline) {
// The input source-map was inline so make the output one inline too.
const firstSource = generatedFile.sources[0];
if (firstSource && (firstSource.rawMap !== null || !sourceFile.isDeclarationFile) &&
firstSource.inline) {
// We render an inline source map if one of:
// * there was no input source map and this is not a typings file;
// * the input source map exists and was inline.
//
// We do not generate inline source maps for typings files unless there explicitly was one in
// the input file because these inline source maps can be very large and it impacts on the
// performance of IDEs that need to read them to provide intellisense etc.
return [
{path: generatedPath, contents: `${generatedFile.contents}\n${mergedMap.toComment()}`}
];

View File

@ -5,7 +5,9 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {fromObject} from 'convert-source-map';
import MagicString from 'magic-string';
import {encode} from 'sourcemap-codec';
import * as ts from 'typescript';
import {absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system';
@ -195,5 +197,47 @@ runInEachFileSystem(() => {
result.find(f => f.path === _('/node_modules/test-package/typings/file.d.ts'))!;
expect(typingsFile.contents).toContain(`\n// ADD MODUlE WITH PROVIDERS PARAMS\n`);
});
it('should render an external source map for files whose original file does not have a source map',
() => {
const {
renderer,
decorationAnalyses,
privateDeclarationsAnalyses,
moduleWithProvidersAnalyses
} = createTestRenderer('test-package', [INPUT_PROGRAM], [INPUT_DTS_PROGRAM]);
const result = renderer.renderProgram(
decorationAnalyses, privateDeclarationsAnalyses, moduleWithProvidersAnalyses);
const typingsFile =
result.find(f => f.path === _('/node_modules/test-package/typings/file.d.ts'))!;
expect(typingsFile.contents).toContain('//# sourceMappingURL=file.d.ts.map');
});
it('should render an internal source map for files whose original file has an internal source map',
() => {
const sourceMap = fromObject({
'version': 3,
'file': 'file.d.ts',
'sources': ['file.d.ts'],
'names': [],
'mappings': encode([[]]),
'sourcesContent': [INPUT_DTS_PROGRAM.contents],
});
INPUT_DTS_PROGRAM.contents += sourceMap.toComment();
const {
renderer,
decorationAnalyses,
privateDeclarationsAnalyses,
moduleWithProvidersAnalyses
} = createTestRenderer('test-package', [INPUT_PROGRAM], [INPUT_DTS_PROGRAM]);
const result = renderer.renderProgram(
decorationAnalyses, privateDeclarationsAnalyses, moduleWithProvidersAnalyses);
const typingsFile =
result.find(f => f.path === _('/node_modules/test-package/typings/file.d.ts'))!;
expect(typingsFile.contents).toContain('//# sourceMappingURL=data:application/json');
});
});
});

View File

@ -640,6 +640,24 @@ UndecoratedBase.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: UndecoratedBase, vie
expect(mapFile.path).toEqual(_('/node_modules/test-package/src/file.js.map'));
expect(JSON.parse(mapFile.contents)).toEqual(MERGED_OUTPUT_PROGRAM_MAP.toObject());
});
it('should render an internal source map for files whose original file does not have a source map',
() => {
const sourceFiles: TestFile[] = [JS_CONTENT];
const {
decorationAnalyses,
renderer,
switchMarkerAnalyses,
privateDeclarationsAnalyses
} = createTestRenderer('test-package', sourceFiles, undefined);
const [sourceFile, mapFile] = renderer.renderProgram(
decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses);
expect(sourceFile.path).toEqual(_('/node_modules/test-package/src/file.js'));
expect(sourceFile.contents)
.toEqual(RENDERED_CONTENTS + '\n' + OUTPUT_PROGRAM_MAP.toComment());
expect(mapFile).toBeUndefined();
});
});
describe('@angular/core support', () => {