fix(core): adhere to bootstrap options for JIT compiled components (#35534)

When using `platformBrowserDynamic().bootstrapModule()`, it is possible
to set `defaultEncapsulation` and `preserveWhitespaces` as default
configuration to influence how components are compiled. When compiling
components in JIT with Ivy, these options were not taken into account.

This commit publishes the options to be globally available, so that the
lazy compilation of JIT components has access to the configured
bootstrap options. Note that this approach does not allow changing the
options once they have been set, as Ivy's compilation model does not
allow for multiple compilations to exist at the same time.

For applications that bootstrap multiple modules, it is now required
to provide the exact same bootstrap options. An error is logged if
incompatible bootstrap options are provided, in which case the updated
options will be ignored.

Fixes #35230
Resolved FW-1838

PR Close #35534
This commit is contained in:
JoostK
2020-02-18 19:55:55 +01:00
committed by Andrew Kushnir
parent c0143cb2ab
commit e342ffd855
7 changed files with 329 additions and 8 deletions

View File

@ -23,6 +23,7 @@ import {ComponentType} from '../interfaces/definition';
import {stringifyForError} from '../util/misc_utils';
import {angularCoreEnv} from './environment';
import {getJitOptions} from './jit_options';
import {flushModuleScopingQueueAsMuchAsPossible, patchComponentDefWithScope, transitiveScopesFor} from './module';
@ -68,18 +69,34 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
throw new Error(error.join('\n'));
}
const jitOptions = getJitOptions();
let preserveWhitespaces = metadata.preserveWhitespaces;
if (preserveWhitespaces === undefined) {
if (jitOptions !== null && jitOptions.preserveWhitespaces !== undefined) {
preserveWhitespaces = jitOptions.preserveWhitespaces;
} else {
preserveWhitespaces = false;
}
}
let encapsulation = metadata.encapsulation;
if (encapsulation === undefined) {
if (jitOptions !== null && jitOptions.defaultEncapsulation !== undefined) {
encapsulation = jitOptions.defaultEncapsulation;
} else {
encapsulation = ViewEncapsulation.Emulated;
}
}
const templateUrl = metadata.templateUrl || `ng:///${type.name}/template.html`;
const meta: R3ComponentMetadataFacade = {
...directiveMetadata(type, metadata),
typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl),
template: metadata.template || '',
preserveWhitespaces: metadata.preserveWhitespaces || false,
template: metadata.template || '', preserveWhitespaces,
styles: metadata.styles || EMPTY_ARRAY,
animations: metadata.animations,
directives: [],
changeDetection: metadata.changeDetection,
pipes: new Map(),
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
pipes: new Map(), encapsulation,
interpolation: metadata.interpolation,
viewProviders: metadata.viewProviders || null,
};

View File

@ -0,0 +1,41 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* 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 {ViewEncapsulation} from '../../metadata/view';
export interface JitCompilerOptions {
defaultEncapsulation?: ViewEncapsulation;
preserveWhitespaces?: boolean;
}
let jitOptions: JitCompilerOptions|null = null;
export function setJitOptions(options: JitCompilerOptions): void {
if (jitOptions !== null) {
if (options.defaultEncapsulation !== jitOptions.defaultEncapsulation) {
ngDevMode &&
console.error(
'Provided value for `defaultEncapsulation` can not be changed once it has been set.');
return;
}
if (options.preserveWhitespaces !== jitOptions.preserveWhitespaces) {
ngDevMode &&
console.error(
'Provided value for `preserveWhitespaces` can not be changed once it has been set.');
return;
}
}
jitOptions = options;
}
export function getJitOptions(): JitCompilerOptions|null {
return jitOptions;
}
export function resetJitOptions(): void {
jitOptions = null;
}