microsoftgraph / microsoft-graph-toolkit

Authentication Providers and UI components for Microsoft Graph 🦒
https://docs.microsoft.com/graph/toolkit/overview
Other
943 stars 303 forks source link

Enable Server Side Rendering #329

Open nmetulev opened 4 years ago

nmetulev commented 4 years ago

Enable components to be rendered on the backend while retaining functionality when running on the front end

pyBlob commented 2 years ago

I just tried enabling mgt-react with Next.js. They have the experimental flag for "esmExternals: true": https://github.com/vercel/next.js/discussions/35217

There are two points that currently prevent loading of mgt-react and its dependencies:

When monkey-patching those manually in the installed files, then you can import more and more of mgt-react.

edit: I just tried using the "next-transpile-modules": const withTM = require("next-transpile-modules")(["@microsoft/mgt-react", "@microsoft/mgt-components", "wc-react"]) This makes the page load, but causes an unhandledRejection "window is not defined" during SSR. Now I see, why it isn't that straight-forward to fix.

sebastienlevert commented 2 years ago

This is quite interesting! Can you share the scenarios on why you are looking at SSR? I'm hearing from what you are saying that we would probably need a cjs module to support SSR today, right?

pyBlob commented 2 years ago

Technically, we don't require SSR for our application, because most pages depend on dynamic user content. However, Next.JS makes it easy for us to share types between database, backend and frontend.

We currently have two problems that prevent using this module without changes:

  1. node-style imports.
  2. lit-html and lit-element need access to the "window" object while executing during SSR (also mentioned in the earlier linked issues).

As for supporting the graph toolkit, one of the following is enough for resolving the imports:

As for adapting lit-html. I haven't had a look at their source, yet. Intuitively, one should only access the "window" object in the hook callbacks of "useEffect" and "useLayoutEffect". If I recall correctly, Next.JS only executes those when the code is loaded by the browser. It should also be possible, to probe "window" and only run the initialization code when it is defined.

sebastienlevert commented 8 months ago

This is related to #2957

web265p3 commented 8 months ago

Maybe its enough (for the beginning) to make it possible to render the components still in the frontend, but remove errors that are generated when depending on "document" in the backend. Probably this is the same for all frameworks, ie Angular Universal or also Next.js

gavinbarron commented 8 months ago

@web265p3 thanks for that feedback.

Unfortunately, that's not going to be trivially feasible in the immediate term due to our current dependency on @azure/msal-browser in the @microsoft/mgt-msal2-provider.

As to the other usages of document, there are number of theming/animation/placement usages that need to use document, and I'm not clear on how we should protect those code paths during SSR.

If you have any expertise or guidance you can share on those aspects of server side rendering of client side components I'd greatly appreciate it.