Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Add rendering context.#2846

Merged
alan-agius4 merged 5 commits intoangular:mainfrom
alan-agius4:server-context
Oct 12, 2022
Merged

Add rendering context.#2846
alan-agius4 merged 5 commits intoangular:mainfrom
alan-agius4:server-context

Conversation

@alan-agius4
Copy link
Collaborator

See each commit

CaerusKaru
CaerusKaru previously approved these changes Oct 11, 2022
@alan-agius4 alan-agius4 added action: merge PR author is ready for this to merge and removed action: review labels Oct 11, 2022
@alan-agius4 alan-agius4 requested a review from dgp1130 as a code owner October 11, 2022 15:01
@alan-agius4 alan-agius4 removed the request for review from dgp1130 October 11, 2022 15:08
@alan-agius4 alan-agius4 force-pushed the server-context branch 2 times, most recently from b97a5cc to e426c21 Compare October 11, 2022 15:16
This provides an easy way to distinguish between SSR, SSG, and client-side apps (CSR).

Closes angular#2612
This provides an easy way to distinguish between SSR, SSG, and client-side apps (CSR).

Closes angular#2612
This is needed as otherwise the build would fail as we try to export `renderModule` multiple times.
This is needed as otherwise `@angular/platform-server` is not resolved correctly.
@alan-agius4 alan-agius4 merged commit 47b42e6 into angular:main Oct 12, 2022
@alan-agius4 alan-agius4 deleted the server-context branch October 12, 2022 13:48

assert(renderModule, `renderModule was not exported from: ${serverBundlePath}.`);
assert(AppServerModule, `AppServerModule was not exported from: ${serverBundlePath}.`);
assert(ɵSERVER_CONTEXT, `ɵSERVER_CONTEXT was not exported from: ${serverBundlePath}.`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @alan-agius4
Are there plans to make ɵSERVER_CONTEXT a public token in v15 (without ɵ symbol prefix)?
It would be great to consume it "legally" in the server angular app.
If I understand correctly, according to above line with assert(), it's also required that the application's code re-exports the token ɵSERVER_CONTEXT (e.g. inmain.server.ts).

// main.server.ts
export { 
   renderModule,
   ɵSERVER_CONTEXT   // <-------------- this is a new _required_ thing
} from '@angular/platform-server';
export { AppServerModule } from './app/app.server.module';

Side note: if it will be required to re-export this token in v15, it would be nice to provide a migration schematics for it in v15.

Copy link

@Platonn Platonn Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my surprise, now I've just created a fresh Angular app with @angular/cli@15.0.0-rc.1 and @nguniversal/express-engine@15.0.0-next.0 and the generated file main.server.ts contains only:

export { AppServerModule } from './app/app.server.module';

and when I'm running yarn prerender I get no errors. However I expected them...

Perhaps I'm missing something in the internals of the prerender builder(?)... how it's possible, that renderModule and ɵSERVER_CONTEXT are exported implicitly from the output main.js bundle?

PS. Regardless of the above analysis, I still think, it would be cool to drop ɵ prefix from ɵSERVER_CONTEXT, if only possible in v15 :)

Copy link

@Platonn Platonn Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Now I've figured out the magic that adds the re-exports of renderModule and ɵSERVER_CONTEXT under the hood! 😅
Merged PR for v15: angular/angular-cli#23866 (in particular those lines: https://github.com/angular/angular-cli/pull/23866/files#diff-e1778745f6c1b0fbef4fe31a8e09d71863363d6980922e3df974c408772025d2R21-R23)

PS. IMHO it seems justified to export SERVER_CONTEXT the same as PLATFROM_ID is exported in the public API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ɵSERVER_CONTEXT is meant to be set internally as such it is considered a private API which it's implementation can change in the future.

Users should not need nor need to set this token.

Copy link

@Platonn Platonn Oct 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that setting this token should be forbidden, but reading value SSG vs SSR it might be useful for applications, when they want to differentiate the behavior of the server app's logic when it's SSR vs SSG.

Let me give an usecase:
Our Angular library has a multisite feature that reads the origin URL (the domain) and makes decisions based on that. It needs to behave differently in SSR and SSG.
In SSR we read the Express' REQUEST injection token (and it's internal properties, including X-Forwarded-Host header). But In SSG we need to use some static (hardcoded/pre-configured) domain, because there is no Express' REQUEST injection token available at the time of prerendering.

Of course we can use some heuristics to solve our case: e.g. when the pre-configured domain is available in the config, use it. Or alternatively when there is no @Optional() REQUEST token provided, assume it's SSG, and use the pre-configured domain value ;)


If Angular framework doesn't expose a token informing about ssr vs ssg, alternatively one can provide the a CUSTOM_SERVER_CONTEXT themselves differently in SSG vs SSR:

  • create 2 pair of files: main.server.ts+app.server.module and main.prerender.ts+app.prerender.module.
  • in the app.server.module provide a token CUSTOM_SERVER_CONTEXT with value 'SSR'
  • in the app.prerender.module provide a token CUSTOM_SERVER_CONTEXT with value 'SSG'
  • in angular.json in the architect section prerender, change the serverTarget, so it points to options.main set to main.prerender.ts

Side note: in that case one need to remember not to rename the module class from AppServerModule to AppPrerenderModule in app.prerender.ts , because nguniversal builder for prerendering will fail - it expects a fixed (hardcoded) name of the module: AppServerModule.

A bit cumbersome / boilerplate - considering that Angular framework could expose it for free... :)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge PR author is ready for this to merge feature target: major This PR is targeted for the next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants