Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform-server): allow shimming the global env sooner #40559

Closed

Conversation

@gkalpak
Copy link
Member

@gkalpak gkalpak commented Jan 25, 2021

@angular/platform-server provides the foundation for rendering an Angular app on the server. In order to achieve that, it uses a server-side DOM implementation (currently domino).

For rendering on the server to work as closely as possible to running the app on the browser, we need to make DOM globals (such as Element, HTMLElement, etc.), which are normally provided by the browser, available as globals on the server as well.

Currently, @angular/platform-server achieves this by extending the global object with the DOM implementation provided by domino. This assignment happens in the setDomTypes() function, which is called in a PLATFORM_INITIALIZER. While this works in most cases, there are some scenarios where the DOM globals are needed sooner (i.e. before initializing the platform). See, for example, #24551 and #39950 for more details on such issues.

This commit provides a way to solve this problem by exposing an side-effect-ful entry-point (@angular/platform-server/shims), that shims the global object with DOM globals. People will be able to import this entry-point in their server-rendered apps before bootstrapping the app (for example, in their main.server.ts file).
(See also #39950 (comment).)

In a future update, the universal schematics will include such an import by default in newly generated projects.

Closes #39950.

Related to angular/angular-cli#19869.

@ngbot ngbot bot modified the milestone: Backlog Jan 25, 2021
@google-cla google-cla bot added the cla: yes label Jan 25, 2021
@gkalpak gkalpak force-pushed the gkalpak:fix-platform-server-load-domino branch from a9d33e8 to 5aae56d Jan 25, 2021
@mary-poppins
Copy link

@mary-poppins mary-poppins commented Jan 25, 2021

gkalpak added a commit to gkalpak/angular-cli that referenced this pull request Jan 25, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/shims`
entry-point was introduced, which can be used to shim the server
environment with APIs normally provided by the browser (such as DOM
globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.
@gkalpak gkalpak force-pushed the gkalpak:fix-platform-server-load-domino branch from 5aae56d to 6340fd7 Jan 26, 2021
@mary-poppins
Copy link

@mary-poppins mary-poppins commented Jan 26, 2021

You can preview 6340fd7 at https://pr40559-6340fd7.ngbuilds.io/.

@gkalpak gkalpak force-pushed the gkalpak:fix-platform-server-load-domino branch from 6340fd7 to f601f3f Jan 26, 2021
@mary-poppins
Copy link

@mary-poppins mary-poppins commented Jan 26, 2021

@gkalpak gkalpak force-pushed the gkalpak:fix-platform-server-load-domino branch from f601f3f to e8626aa Jan 27, 2021
@mary-poppins
Copy link

@mary-poppins mary-poppins commented Jan 27, 2021

@gkalpak gkalpak marked this pull request as ready for review Jan 27, 2021
@pullapprove pullapprove bot requested review from josephperrott and kyliau Jan 27, 2021
@gkalpak gkalpak added action: review and removed state: WIP labels Jan 27, 2021
@gkalpak
Copy link
Member Author

@gkalpak gkalpak commented Jan 27, 2021

I have updated the example to not use @nguniversal dependencies. PTAL, @alan-agius4.

@gkalpak gkalpak requested a review from alan-agius4 Jan 27, 2021
@gkalpak
Copy link
Member Author

@gkalpak gkalpak commented Feb 9, 2021

How likely is it that someone might want to provide an alternate set of shims?

Not very likely (but not impossible either). I mean, I am sure people might want to provide more shims on top of the domino ones, but instead of the domino ones.

In any case, that should be easy to do: they simply won't import @angular/platform-server/shims.

(Also, note that we are already providing the shims at a later stage (once the app bootstraps). This PR only makes it possible to provide the shims earlier in the process).

On the init vs shims front, I could still seeing calling this shims if there's not any other type of side-effectful initialization that would ever need to happen. Consistency is also good, though.

I guess it is hard to tell whether we might need more initialization that just shims in the future. (I don't see it as very likely, but we can't rule it out either.)

Since most people seem to be pro init, I am going to change it to that.

Also- should we be worried about code formatters re-ordering imports?

Yes, that would be a problem (although it is arguably not a great idea to re-order imports, since they can have side effects). Note, we had reports of issues due to re-ordering other side-effect-ful imports (e.g. zone.js/dist/zone-testing): #40305

There is not much we can do, I guess. In angular/angular-cli#19869, which makes adding this import part of the universal schematic, I have added a note above the import explaining that it should come before other imports that rely on DOM built-ins: https://github.com/angular/angular-cli/pull/19869/files#diff-ea3f134f2268461f0fbee755a6bc4340bf729674e338317903484027e4fec71fR4

@gkalpak gkalpak force-pushed the gkalpak:fix-platform-server-load-domino branch from 81c0521 to 5392175 Feb 9, 2021
@mary-poppins
Copy link

@mary-poppins mary-poppins commented Feb 9, 2021

@gkalpak
Copy link
Member Author

@gkalpak gkalpak commented Feb 9, 2021

Comments addressed (the main change is renaming the entry-point from shims to init).

Copy link
Contributor

@jessicajaniuk jessicajaniuk left a comment

LGTM

reviewed-for: public-api

alxhub added a commit that referenced this pull request Feb 9, 2021
…#40737)

Previously, if an entry-point had no public exports (such as the
`@angular/platform-server/shims` introduced in #40559, which is a
side-effect-ful entry-point), it was incorrectly marked as having all
its exports deprecated (which marks the entry-point as deprecated as
well).

This commit fixes this by ensuring that an entry-point is not marked as
having all its exports deprecated if it has no public exports.

PR Close #40737
alxhub added a commit that referenced this pull request Feb 9, 2021
…#40737)

Previously, if an entry-point had no public exports (such as the
`@angular/platform-server/shims` introduced in #40559, which is a
side-effect-ful entry-point), it was incorrectly marked as having all
its exports deprecated (which marks the entry-point as deprecated as
well).

This commit fixes this by ensuring that an entry-point is not marked as
having all its exports deprecated if it has no public exports.

PR Close #40737
alxhub added a commit that referenced this pull request Feb 9, 2021
…#40737)

Previously, if an entry-point had no public exports (such as the
`@angular/platform-server/shims` introduced in #40559, which is a
side-effect-ful entry-point), it was incorrectly marked as having all
its exports deprecated (which marks the entry-point as deprecated as
well).

This commit fixes this by ensuring that an entry-point is not marked as
having all its exports deprecated if it has no public exports.

PR Close #40737
Copy link
Member

@jelbourn jelbourn left a comment

LGTM

Reviewed-for: public-api

@gkalpak gkalpak removed the request for review from alxhub Feb 9, 2021
@gkalpak gkalpak added action: merge and removed action: review labels Feb 9, 2021
gkalpak added 6 commits Feb 11, 2021
The `platform-server` package currently depends on the [domino][1]
package. This commit adds `domino` to the list of dependencies for the
`platform-server` `ng_module` target.

[1]: https://www.npmjs.com/package/domino
This commit adds an integration test that uses `@angular/elements` with
`@angular/platform-server` in order to highlight a current
incompatibility. The issue will be fixed in a subsequent commit.
`@angular/platform-server` provides the foundation for rendering an
Angular app on the server. In order to achieve that, it uses a
server-side DOM implementation (currently [domino][1]).

For rendering on the server to work as closely as possible to running
the app on the browser, we need to make DOM globals (such as `Element`,
`HTMLElement`, etc.), which are normally provided by the browser,
available as globals on the server as well.

Currently, `@angular/platform-server` achieves this by extending the
`global` object with the DOM implementation provided by `domino`. This
assignment happens in the [setDomTypes()][2] function, which is
[called in a `PLATFORM_INITIALIZER`][3]. While this works in most cases,
there are some scenarios where the DOM globals are needed sooner (i.e.
before initializing the platform). See, for example, #24551 and #39950
for more details on such issues.

This commit provides a way to solve this problem by exposing a
side-effect-ful entry-point (`@angular/platform-server/init`), that
shims the `global` object with DOM globals. People will be able to
import this entry-point in their server-rendered apps before
bootstrapping the app (for example, in their `main.server.ts` file).
(See also [#39950 (comment)][4].)

In a future update, the [`universal` schematics][5] will include such an
import by default in newly generated projects.

[1]: https://www.npmjs.com/package/domino
[2]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/domino_adapter.ts#L17-L21
[3]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/server.ts#L33
[4]: #39950 (comment)
[5]: https://github.com/angular/angular-cli/blob/cc51432661eb4ab4b6a3/packages/schematics/angular/universal
@gkalpak gkalpak force-pushed the gkalpak:fix-platform-server-load-domino branch from 5392175 to a67a720 Feb 11, 2021
@mary-poppins
Copy link

@mary-poppins mary-poppins commented Feb 11, 2021

josephperrott added a commit that referenced this pull request Feb 12, 2021
This commit adds an integration test that uses `@angular/elements` with
`@angular/platform-server` in order to highlight a current
incompatibility. The issue will be fixed in a subsequent commit.

PR Close #40559
josephperrott added a commit that referenced this pull request Feb 12, 2021
`@angular/platform-server` provides the foundation for rendering an
Angular app on the server. In order to achieve that, it uses a
server-side DOM implementation (currently [domino][1]).

For rendering on the server to work as closely as possible to running
the app on the browser, we need to make DOM globals (such as `Element`,
`HTMLElement`, etc.), which are normally provided by the browser,
available as globals on the server as well.

Currently, `@angular/platform-server` achieves this by extending the
`global` object with the DOM implementation provided by `domino`. This
assignment happens in the [setDomTypes()][2] function, which is
[called in a `PLATFORM_INITIALIZER`][3]. While this works in most cases,
there are some scenarios where the DOM globals are needed sooner (i.e.
before initializing the platform). See, for example, #24551 and #39950
for more details on such issues.

This commit provides a way to solve this problem by exposing a
side-effect-ful entry-point (`@angular/platform-server/init`), that
shims the `global` object with DOM globals. People will be able to
import this entry-point in their server-rendered apps before
bootstrapping the app (for example, in their `main.server.ts` file).
(See also [#39950 (comment)][4].)

In a future update, the [`universal` schematics][5] will include such an
import by default in newly generated projects.

[1]: https://www.npmjs.com/package/domino
[2]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/domino_adapter.ts#L17-L21
[3]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/server.ts#L33
[4]: #39950 (comment)
[5]: https://github.com/angular/angular-cli/blob/cc51432661eb4ab4b6a3/packages/schematics/angular/universal

PR Close #40559
gkalpak added a commit to gkalpak/angular-cli that referenced this pull request Feb 12, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/init`
entry-point was introduced, which can be used to initialize the server
environment by providing shims for APIs normally provided by the browser
(such as DOM globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.

Fixes angular/angular#40559
gkalpak added a commit to gkalpak/angular-cli that referenced this pull request Feb 12, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/init`
entry-point was introduced, which can be used to initialize the server
environment by providing shims for APIs normally provided by the browser
(such as DOM globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.

Fixes angular/angular#40559
gkalpak added a commit to gkalpak/angular-cli that referenced this pull request Feb 12, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/init`
entry-point was introduced, which can be used to initialize the server
environment by providing shims for APIs normally provided by the browser
(such as DOM globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.

Fixes angular/angular#40559
@gkalpak gkalpak deleted the gkalpak:fix-platform-server-load-domino branch Feb 16, 2021
gkalpak added a commit to gkalpak/angular-cli that referenced this pull request Feb 17, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/init`
entry-point was introduced, which can be used to initialize the server
environment by providing shims for APIs normally provided by the browser
(such as DOM globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.

Fixes angular/angular#40559
gkalpak added a commit to gkalpak/angular-cli that referenced this pull request Feb 17, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/init`
entry-point was introduced, which can be used to initialize the server
environment by providing shims for APIs normally provided by the browser
(such as DOM globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.

Fixes angular/angular#40559
alan-agius4 added a commit to angular/angular-cli that referenced this pull request Feb 18, 2021
…platform-server` shims

In angular/angular#40559, a new `@angular/platform-server/init`
entry-point was introduced, which can be used to initialize the server
environment by providing shims for APIs normally provided by the browser
(such as DOM globals).

If the project is using a version of Angular (and thus
`@angular/platform-server`) that is known to include this new
entry-point, the newly generated `main.server.ts` file should import it
at the top in order to ensure that the shims will be available as soon
as possible (before other direct or transitive imports that may rely on
them). See also angular/angular#40559 for more details.

NOTE:
This `universal` schematic is the base for `app-shell`,
`@nguniversal/express-engine` and `@nguniversal/hapi-engine`.

Fixes angular/angular#40559
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment