mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(platform-browser): add context to createApplication
This is necessary to use SSR safely with `createApplication` and avoid constraining users to `bootstrapApplication`. It is one more step towards feature parity between `createApplication` and `bootstrapApplication`.
This commit is contained in:
committed by
Andrew Kushnir
parent
ab67988d2e
commit
ec9dc94cee
@@ -52,7 +52,7 @@ export class By {
|
||||
}
|
||||
|
||||
// @public
|
||||
export function createApplication(options?: ApplicationConfig): Promise<ApplicationRef>;
|
||||
export function createApplication(options?: ApplicationConfig, context?: BootstrapContext): Promise<ApplicationRef>;
|
||||
|
||||
// @public
|
||||
export function disableDebugTools(): void;
|
||||
|
||||
@@ -131,8 +131,7 @@ export async function bootstrapApplication(
|
||||
): Promise<ApplicationRef> {
|
||||
const config = {
|
||||
rootComponent,
|
||||
platformRef: context?.platformRef,
|
||||
...createProvidersConfig(options),
|
||||
...createProvidersConfig(options, context),
|
||||
};
|
||||
|
||||
if ((typeof ngJitMode === 'undefined' || ngJitMode) && typeof fetch === 'function') {
|
||||
@@ -150,20 +149,27 @@ export async function bootstrapApplication(
|
||||
*
|
||||
* @param options Extra configuration for the application environment, see `ApplicationConfig` for
|
||||
* additional info.
|
||||
* @param context Optional context object that can be used to provide a pre-existing
|
||||
* platform injector. This is useful for advanced use-cases, for example, server-side
|
||||
* rendering, where the platform is created for each request.
|
||||
* @returns A promise that returns an `ApplicationRef` instance once resolved.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export async function createApplication(options?: ApplicationConfig): Promise<ApplicationRef> {
|
||||
export async function createApplication(
|
||||
options?: ApplicationConfig,
|
||||
context?: BootstrapContext,
|
||||
): Promise<ApplicationRef> {
|
||||
if ((typeof ngJitMode === 'undefined' || ngJitMode) && typeof fetch === 'function') {
|
||||
await resolveJitResources();
|
||||
}
|
||||
|
||||
return internalCreateApplication(createProvidersConfig(options));
|
||||
return internalCreateApplication(createProvidersConfig(options, context));
|
||||
}
|
||||
|
||||
function createProvidersConfig(options?: ApplicationConfig) {
|
||||
function createProvidersConfig(options?: ApplicationConfig, context?: BootstrapContext) {
|
||||
return {
|
||||
platformRef: context?.platformRef,
|
||||
appProviders: [...BROWSER_MODULE_PROVIDERS, ...(options?.providers ?? [])],
|
||||
platformProviders: INTERNAL_BROWSER_PLATFORM_PROVIDERS,
|
||||
};
|
||||
|
||||
@@ -47,10 +47,12 @@ import {
|
||||
provideNgReflectAttributes,
|
||||
ɵSSR_CONTENT_INTEGRITY_MARKER as SSR_CONTENT_INTEGRITY_MARKER,
|
||||
provideZoneChangeDetection,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {
|
||||
bootstrapApplication,
|
||||
createApplication,
|
||||
BootstrapContext,
|
||||
BrowserModule,
|
||||
provideClientHydration,
|
||||
@@ -767,6 +769,24 @@ class HiddenModule {}
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
it('should render with `createApplication`', async () => {
|
||||
const output = await renderApplication(
|
||||
async (context) => {
|
||||
const appRef = await createApplication(
|
||||
{
|
||||
providers: [provideZoneChangeDetection()],
|
||||
},
|
||||
context,
|
||||
);
|
||||
appRef.bootstrap(createMyAsyncServerApp(true));
|
||||
return appRef;
|
||||
},
|
||||
{document: doc},
|
||||
);
|
||||
|
||||
expect(output).toBe(expectedOutput);
|
||||
});
|
||||
|
||||
it('using long form should work', async () => {
|
||||
const platform = platformServer([
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user