feat: introduce source maps for templates (#15011)
The main use case for the generated source maps is to give errors a meaningful context in terms of the original source that the user wrote. Related changes that are included in this commit: * renamed virtual folders used for jit: * ng://<module type>/module.ngfactory.js * ng://<module type>/<comp type>.ngfactory.js * ng://<module type>/<comp type>.html (for inline templates) * error logging: * all errors that happen in templates are logged from the place of the nearest element. * instead of logging error messages and stacks separately, we log the actual error. This is needed so that browsers apply source maps to the stack correctly. * error type and error is logged as one log entry. Note that long-stack-trace zone has a bug that disables source maps for stack traces, see https://github.com/angular/zone.js/issues/661. BREAKING CHANGE: - DebugNode.source no more returns the source location of a node. Closes 14013
This commit is contained in:

committed by
Chuck Jazdzewski

parent
1c1085b140
commit
cdc882bd36
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import {ChangeDetectionStrategy, ComponentFactory, RendererType2, SchemaMetadata, Type, ViewEncapsulation, ɵLifecycleHooks, ɵreflector, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {StaticSymbol} from './aot/static_symbol';
|
||||
import {CssSelector} from './selector';
|
||||
import {splitAtColon} from './util';
|
||||
@ -257,6 +258,7 @@ export class CompileTemplateMetadata {
|
||||
encapsulation: ViewEncapsulation;
|
||||
template: string;
|
||||
templateUrl: string;
|
||||
isInline: boolean;
|
||||
styles: string[];
|
||||
styleUrls: string[];
|
||||
externalStylesheets: CompileStylesheetMetadata[];
|
||||
@ -265,7 +267,7 @@ export class CompileTemplateMetadata {
|
||||
interpolation: [string, string];
|
||||
constructor(
|
||||
{encapsulation, template, templateUrl, styles, styleUrls, externalStylesheets, animations,
|
||||
ngContentSelectors, interpolation}: {
|
||||
ngContentSelectors, interpolation, isInline}: {
|
||||
encapsulation?: ViewEncapsulation,
|
||||
template?: string,
|
||||
templateUrl?: string,
|
||||
@ -275,6 +277,7 @@ export class CompileTemplateMetadata {
|
||||
ngContentSelectors?: string[],
|
||||
animations?: any[],
|
||||
interpolation?: [string, string],
|
||||
isInline?: boolean
|
||||
} = {}) {
|
||||
this.encapsulation = encapsulation;
|
||||
this.template = template;
|
||||
@ -288,6 +291,7 @@ export class CompileTemplateMetadata {
|
||||
throw new Error(`'interpolation' should have a start and an end symbol.`);
|
||||
}
|
||||
this.interpolation = interpolation;
|
||||
this.isInline = isInline;
|
||||
}
|
||||
|
||||
toSummary(): CompileTemplateSummary {
|
||||
@ -524,7 +528,8 @@ export function createHostComponentMeta(
|
||||
styles: [],
|
||||
styleUrls: [],
|
||||
ngContentSelectors: [],
|
||||
animations: []
|
||||
animations: [],
|
||||
isInline: true,
|
||||
}),
|
||||
changeDetection: ChangeDetectionStrategy.Default,
|
||||
inputs: [],
|
||||
@ -752,3 +757,41 @@ export function flatten<T>(list: Array<T|T[]>): T[] {
|
||||
return (<T[]>flat).concat(flatItem);
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Using `location.origin` as prefix helps displaying them as a hierarchy in chrome.
|
||||
* It also helps long-stack-trace zone when rewriting stack traces to not break
|
||||
* source maps (as now all scripts have the same origin).
|
||||
*/
|
||||
function ngJitFolder() {
|
||||
return 'ng://';
|
||||
}
|
||||
|
||||
export function templateSourceUrl(
|
||||
ngModuleType: CompileIdentifierMetadata, compMeta: {type: CompileIdentifierMetadata},
|
||||
templateMeta: {isInline: boolean, templateUrl: string}) {
|
||||
if (templateMeta.isInline) {
|
||||
if (compMeta.type.reference instanceof StaticSymbol) {
|
||||
return compMeta.type.reference.filePath;
|
||||
} else {
|
||||
return `${ngJitFolder()}/${identifierName(ngModuleType)}/${identifierName(compMeta.type)}.html`;
|
||||
}
|
||||
} else {
|
||||
return templateMeta.templateUrl;
|
||||
}
|
||||
}
|
||||
|
||||
export function sharedStylesheetJitUrl(meta: CompileStylesheetMetadata, id: number) {
|
||||
const pathParts = meta.moduleUrl.split(/\/\\/g);
|
||||
const baseName = pathParts[pathParts.length - 1];
|
||||
return `${ngJitFolder()}/css/${id}${baseName}.ngstyle.js`;
|
||||
}
|
||||
|
||||
export function ngModuleJitUrl(moduleMeta: CompileNgModuleMetadata): string {
|
||||
return `${ngJitFolder()}/${identifierName(moduleMeta.type)}/module.ngfactory.js`;
|
||||
}
|
||||
|
||||
export function templateJitUrl(
|
||||
ngModuleType: CompileIdentifierMetadata, compMeta: CompileDirectiveMetadata): string {
|
||||
return `${ngJitFolder()}/${identifierName(ngModuleType)}/${identifierName(compMeta.type)}.ngfactory.js`;
|
||||
}
|
||||
|
Reference in New Issue
Block a user