-
Notifications
You must be signed in to change notification settings - Fork 23
feat(ServerComponent): add method to render simplified html #1072
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
base: main
Are you sure you want to change the base?
Conversation
|
b65d50c was deployed to: https://fred-pr1072.review.mdn.allizom.net/ |
caugner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we avoid renderSimple() if an environment variable just caused this effect?
components/outer-layout/server.js
Outdated
| render(context, markup) { | ||
| const asyncStore = asyncLocalStorage.getStore(); | ||
| if (!asyncStore) { | ||
| if (!asyncStore || "renderSimple" in asyncStore) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would renderSimple end up in asyncStore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't in the outer layout, since we don't call it from the renderSimple root function: this is simply to make typescript happy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize that I don't fully understand what asyncLocalStorage holds.
I looked at https://github.com/mdn/fred/blob/22628366e1b9ecc0d8f36811492c5a6f08e62db4/components/server/async-local-storage.js and it doesn't have any information, it just creates an instance of AsyncLocalStorage without any semantic notion of what it contains.
It is not clear to me why "renderSimple" in asyncStore implies that asyncLocalStorage is missing. It would probably be better to throw a separate error in this case, because if asyncStore is truthy, it's apparently not missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's a little bit esoteric: the top level render methods (in entry.ssr.js) populate it. I'll add a jsdoc comment or similar to explain what's going on, and point back to there.
Agreed on the error, that was just me being a little lazy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment, and realised the name of AsyncLocalStorageContents may have seemed a little "official" - like it was coming from node itself - rather than something we had defined so renamed it, in 198df40 (#1072)
LeoMcA
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we avoid renderSimple() if an environment variable just caused this effect?
Hmm, let me think about this: I think though it would make the component code more complex, and I think there's a nice simplicity to just having two render methods on components which need them.
components/outer-layout/server.js
Outdated
| render(context, markup) { | ||
| const asyncStore = asyncLocalStorage.getStore(); | ||
| if (!asyncStore) { | ||
| if (!asyncStore || "renderSimple" in asyncStore) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't in the outer layout, since we don't call it from the renderSimple root function: this is simply to make typescript happy.
caugner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall, just three more nits:
- Should the method be called
renderSimplified()orrenderMinimal()to make it clearer what this method does. - Can we mention this in the docs (README?).
- Could every
renderSimple()implementation incl. default implementation explain in JSDoc what it omits?
| /** | ||
| * @param {...any} args | ||
| * @returns {any} | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add description of this method
| /** | ||
| * @param {import("@fred").Context<import("@rari").DocPage>} context | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: explain what this method omits (even if it's comparably trivial from looking at render/renderSimple side-by-side
| /** | ||
| * @param {import("@fred").Context<import("@rari").DocPage>} context | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: explain what this simplified/minimal rendering omits
| * Store for internal context passed around components. | ||
| * | ||
| * Generally only used within the `ServerComponent` class itself, | ||
| * or very special server components (such as the `OuterLayout`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can you give an example?
Description
renderSimplemethod to the server component class, which can be overwritten in a component to define a simplified HTML version of the componentMotivation
renderSimpleexport inentry.ssr.jsI don't have to set up async local storage, mock fluent, etc.Testing
For a preview of the simple form of a component, run:
And then navigate directly to a doc page (other page types will render nothing), e.g. http://localhost:3000/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger
Screenshot