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:
@ -6,6 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import './util/ng_jit_mode';
|
||||
|
||||
import {Observable, Observer, Subscription, merge} from 'rxjs';
|
||||
import {share} from 'rxjs/operators';
|
||||
|
||||
@ -29,6 +31,7 @@ import {isComponentResourceResolutionQueueEmpty, resolveComponentResources} from
|
||||
import {assertNgModuleType} from './render3/assert';
|
||||
import {ComponentFactory as R3ComponentFactory} from './render3/component_ref';
|
||||
import {setLocaleId} from './render3/i18n';
|
||||
import {setJitOptions} from './render3/jit/jit_options';
|
||||
import {NgModuleFactory as R3NgModuleFactory} from './render3/ng_module_ref';
|
||||
import {publishDefaultGlobalUtils as _publishDefaultGlobalUtils} from './render3/util/global_utils';
|
||||
import {Testability, TestabilityRegistry} from './testability/testability';
|
||||
@ -56,13 +59,27 @@ export function compileNgModuleFactory__POST_R3__<M>(
|
||||
injector: Injector, options: CompilerOptions,
|
||||
moduleType: Type<M>): Promise<NgModuleFactory<M>> {
|
||||
ngDevMode && assertNgModuleType(moduleType);
|
||||
|
||||
const compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options);
|
||||
|
||||
if (typeof ngJitMode === 'undefined' || ngJitMode) {
|
||||
// Configure the compiler to use the provided options. This call may fail when multiple modules
|
||||
// are bootstrapped with incompatible options, as a component can only be compiled according to
|
||||
// a single set of options.
|
||||
setJitOptions({
|
||||
defaultEncapsulation:
|
||||
_lastDefined(compilerOptions.map(options => options.defaultEncapsulation)),
|
||||
preserveWhitespaces:
|
||||
_lastDefined(compilerOptions.map(options => options.preserveWhitespaces)),
|
||||
});
|
||||
}
|
||||
|
||||
const moduleFactory = new R3NgModuleFactory(moduleType);
|
||||
|
||||
if (isComponentResourceResolutionQueueEmpty()) {
|
||||
return Promise.resolve(moduleFactory);
|
||||
}
|
||||
|
||||
const compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options);
|
||||
const compilerProviders = _mergeArrays(compilerOptions.map(o => o.providers !));
|
||||
|
||||
// In case there are no compiler providers, we just return the module factory as
|
||||
@ -748,6 +765,15 @@ function remove<T>(list: T[], el: T): void {
|
||||
}
|
||||
}
|
||||
|
||||
function _lastDefined<T>(args: T[]): T|undefined {
|
||||
for (let i = args.length - 1; i >= 0; i--) {
|
||||
if (args[i] !== undefined) {
|
||||
return args[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function _mergeArrays(parts: any[][]): any[] {
|
||||
const result: any[] = [];
|
||||
parts.forEach((part) => part && result.push(...part));
|
||||
|
Reference in New Issue
Block a user