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(core): use react-helmet-async #6306

Merged
merged 13 commits into from
Feb 2, 2022
Merged

feat(core): use react-helmet-async #6306

merged 13 commits into from
Feb 2, 2022

Conversation

seyoon20087
Copy link
Contributor

@seyoon20087 seyoon20087 commented Jan 10, 2022

Motivation

Utilize react-helmet-async on @docusaurus/Head

See the description in each commit for a reason why I did this.

Have you read the Contributing Guidelines on pull requests?

Yes

Test Plan

  1. Replace react-helmet with react-helmet-async in packages/docusaurus
  2. Include HelmetProvider in both client and server

Related PRs

N/A

Even though Strict Mode is not required a WARNING icon now displays
on all components that do not use React.StrictMode on React DevTools extension.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
react-helmet is NOT thread safe, as explained in https://open.nytimes.com/the-future-of-meta-tag-management-for-modern-react-development-ec26a7dc9183#fdc2

Therefore, it's better if react-helmet-async is utilized instead of react-helmet.

Even though react-helmet-async is being utilized, most users will not require any code changes to @docusaurus/Head since it uses the same API as react-helmet.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
I forgot to do this before.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
@facebook-github-bot facebook-github-bot added the CLA Signed Signed Facebook CLA label Jan 10, 2022
@netlify
Copy link

netlify bot commented Jan 10, 2022

✔️ [V2]
Built without sensitive environment variables

🔨 Explore the source changes: 4f2ddd1

🔍 Inspect the deploy log: https://app.netlify.com/sites/docusaurus-2/deploys/61fa26ba7ec05600089c56dc

😎 Browse the preview: https://deploy-preview-6306--docusaurus-2.netlify.app

@github-actions
Copy link

github-actions bot commented Jan 10, 2022

⚡️ Lighthouse report for the changes in this PR:

Category Score
🟠 Performance 66
🟢 Accessibility 100
🟢 Best practices 100
🟢 SEO 100
🟢 PWA 92

Lighthouse ran on https://deploy-preview-6306--docusaurus-2.netlify.app/

@Josh-Cena
Copy link
Collaborator

Great, it makes sense to me 👍

Strict mode may cause surprising useEffect magic to some users, but I guess it's mostly fine

@Josh-Cena Josh-Cena changed the title Utilize React Strict Mode (on client) and react-helmet-async (on @docusaurus/Head) feat: use React Strict Mode and react-helmet-async Jan 10, 2022
@Josh-Cena Josh-Cena changed the title feat: use React Strict Mode and react-helmet-async feat(core): use React Strict Mode and react-helmet-async Jan 10, 2022
@Josh-Cena Josh-Cena added the pr: polish This PR adds a very minor behavior improvement that users will enjoy. label Jan 10, 2022
@slorber
Copy link
Collaborator

slorber commented Jan 12, 2022

Thanks 👍 Definitively something I wanted to do.

Will review this more carefully and see potential side-effects for users later

</BrowserRouter>,
<React.StrictMode>
<BrowserRouter>
<HelmetProvider>
Copy link
Collaborator

Choose a reason for hiding this comment

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

for consistency between client/server, maybe apply the new provider above the router in both cases?

@@ -83,19 +83,23 @@ async function doRender(locals: Locals & {path: string}) {
const modules = new Set<string>();
const context = {};

const helmetContext = {};
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe type this instead and use ! or a if(!context.helmet) guard

Copy link
Collaborator

Choose a reason for hiding this comment

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

This how the HelmetProvider is supposed to work. Type for HelmetProvider.props.context is {} although I suspect that's just a bad typing and they really just mean Record<string, never>

<App />
</ProvideLinksCollector>
</StaticRouter>
<HelmetProvider context={helmetContext}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

probably worth applying strict mode here too for security, even if I doubt it will be very useful (only enabled in prod) we may enable some SSR in development mode in the future.

See also https://twitter.com/sebastienlorber/status/1481295361016745984

@Josh-Cena Josh-Cena requested a review from slorber January 14, 2022 01:09
Copy link
Collaborator

@slorber slorber left a comment

Choose a reason for hiding this comment

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

This works in prod, but produces a lot of warnings in dev due to react-loadable

Unless we update our react-loadable fork (https://github.com/slorber/react-loadable?organization=slorber&organization=slorber), it's not possible to enable strict mode above the route components, so at most it can be just above the layout

image

React-loadable is using the very old React context feature: https://github.com/slorber/react-loadable/blob/master/src/index.js#L278 and lots of UNSAFE lifecycles

@slorber slorber marked this pull request as draft January 20, 2022 18:19
@seyoon20087 seyoon20087 marked this pull request as ready for review January 22, 2022 01:46
@seyoon20087 seyoon20087 marked this pull request as draft January 22, 2022 03:01
@seyoon20087 seyoon20087 requested a review from slorber January 22, 2022 03:01
@Josh-Cena
Copy link
Collaborator

Hey, you are certainly doing something wrong with your branch😅 Just try rebase main

@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Jan 22, 2022

@seyoon20087 Can you handle this? Maybe you want to sit back and let me fix your branch? I'm getting lots of notifications of these commits.

@seyoon20087
Copy link
Contributor Author

Sure you may fix them

@Josh-Cena
Copy link
Collaborator

So, we for sure don't want to maintain these dependencies in this repo. FYI, we have just acquired an organization where we can host our forked dependencies. If there are incompatible dependencies (e.g. react-loadable) we will fix it in our forked versions. We have already forked react-loadable, so there's nothing you need to do.

@seyoon20087
Copy link
Contributor Author

The forked react-loadable package had some warnings logged in the console, as described here...

@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Jan 22, 2022

Yes, we will continue to improve on our fork or inspect other alternatives, but for now there isn't a decision yet. react-loadble is a bit complicated, because we may not use this dependency at all in the near future. But for sure, we would not want to self-host a script file like you currently do.

Both unforked react-loadable and @docusaurus/react-loadable uses legacy React APIs.

However, @react-loadable/revised (https://github.com/react-loadable/revised) is actively maintained and widely used in production, thus replaced with this package.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
@seyoon20087 seyoon20087 marked this pull request as ready for review January 22, 2022 17:15
@seyoon20087
Copy link
Contributor Author

seyoon20087 commented Jan 22, 2022

This works in prod, but produces a lot of warnings in dev due to react-loadable

Unless we update our react-loadable fork (https://github.com/slorber/react-loadable?organization=slorber&organization=slorber), it's not possible to enable strict mode above the route components, so at most it can be just above the layout

image

React-loadable is using the very old React context feature: https://github.com/slorber/react-loadable/blob/master/src/index.js#L278 and lots of UNSAFE lifecycles

@slorber I just fixed the issue. Could you take a look?

Copy link
Collaborator

@slorber slorber left a comment

Choose a reason for hiding this comment

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

Didn't know about this revised fork (https://github.com/react-loadable/revised)
That looks suitable to replace our own fork (https://github.com/slorber/react-loadable)

TS problems to fix

  • why not using the latest version?

I'll check later to see if strict mode works


Changing the fork is a quite important change, considering the implementation is totally refactored. We'd rather have 2 separate PRs: one for the fork and one for strict mode

@@ -44,7 +44,7 @@
"@docusaurus/cssnano-preset": "2.0.0-beta.15",
"@docusaurus/logger": "2.0.0-beta.15",
"@docusaurus/mdx-loader": "2.0.0-beta.15",
"@docusaurus/react-loadable": "5.5.2",
"@docusaurus/react-loadable": "npm:@react-loadable/[email protected]",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"@docusaurus/react-loadable": "npm:@react-loadable/revised@0.0.26",
"@react-loadable/revised": "0.0.26",

Also why not using the latest version? 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

Curious why we had this package alias? To trick TS and get the correct typedefs?

Copy link
Collaborator

Choose a reason for hiding this comment

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

which package alias? @docusaurus/react-loadable is our fork, we can't use just react-loadable

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes I know, but we still imported react-loadable in the code. Is that so we get the correct type defs from @types/react-loadable?

@Josh-Cena
Copy link
Collaborator

My thought was that we should have had a separate PR for react-helmet-async. That way this PR would have made it into the last release instead of being blocked till now.

@seyoon20087 seyoon20087 changed the title feat(core): use React Strict Mode and react-helmet-async feat(core): use react-helmet-async on @docusaurus/Head Jan 28, 2022
@Josh-Cena Josh-Cena requested a review from slorber January 28, 2022 07:53
@seyoon20087 seyoon20087 changed the title feat(core): use react-helmet-async on @docusaurus/Head feat(core): use React Strict Mode and react-helmet-async Jan 28, 2022
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
@slorber
Copy link
Collaborator

slorber commented Jan 28, 2022

Can we split this PR in 3 so that easy part can be easily merged/reviewed/discussed separately?

  • use react-helmet-async
  • use @react-loadable/revised
  • use StrictMode

All those things are quite unrelated and some are safer than others, so lets merge these changes one at a time

@seyoon20087
Copy link
Contributor Author

seyoon20087 commented Jan 28, 2022 via email

@Josh-Cena Josh-Cena changed the title feat(core): use React Strict Mode and react-helmet-async feat(core): use react-helmet-async Feb 2, 2022
Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

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

We'll merge this one with only the react-helmet change. I'll cherry-pick the other changes into a new PR.

@Josh-Cena Josh-Cena merged commit a615ab3 into facebook:main Feb 2, 2022
Josh-Cena added a commit that referenced this pull request Feb 2, 2022
author Joshua Chen <[email protected]> 1643786935 +0800
committer Joshua Chen <[email protected]> 1643786935 +0800
gpgsig -----BEGIN PGP SIGNATURE-----

 iQIzBAABCAAdFiEE/nJvfdEj7jAI5zKOw3FFuBi9to8FAmH6Mr0ACgkQw3FFuBi9
 to9wSg//WhlHmJqJenph18u1J8+W0ApnIOoSq9dck7SUjbVWbwZyUgAkgUnhZAu8
 PMIl/EuIPc55jvXXQ/Vd2mtIMlHTGZA9z1I0JVZwdAag59acF/aJQAZxp6RhtWjX
 6wDqc09ZRU4C8QylY6ShAFkOsewmzcCuu/tdiQbirPE3tD1qYRyZLwnru0FAzqzo
 V2kI6lgJMn6AVb1oqkm5lzAwxTqzet9h89z/37O0xFbBEzz3Yk26LxR8Voq2f4Tk
 8XUwn1X9rRB41fGD8IkT+M23VJG2oLktcuxcSsBSTiomDtPl47ujpouBEtMTJynk
 wJRS/asbEM8Qu3/ayXjLFSfQhZK9ITZ3QIx9AF5gMVe2WkVAUX2voh4PYN2BSrd/
 +wP/jE3Fv+cmjg6BnYeaN1xzH02QU6kwGDnvb8sw9ldnPiEWQqLqjPDPUaNTn4CH
 iw30Lt+WUCwtJFCKoPjQmviC6lvvqc5Neoqm+nBoPxHdW4dVHHSOXAzZUqD/TPcZ
 Yz5fLJi7ADj6SJL/lBxvQznFM914gmYteKxyN8QyV9qVYCtYuL5GpbK+ttEFLwMz
 uCaLYjDY8ZsjBqFLIXasQu49lBzLRSevc0XGME+acsh8l1cR46/kHIuV1LL5DgyT
 EAfRuTiMobBI+ycaelsEqgF4lW/F2Gzigjs6NmJ8/gGwHt0YjmA=
 =n38o
 -----END PGP SIGNATURE-----

feat(core): use react-helmet-async (#6306)

* Use React Strict Mode

Even though Strict Mode is not required a WARNING icon now displays
on all components that do not use React.StrictMode on React DevTools extension.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

* Utilize react-helmet-async instead of react-helmet

react-helmet is NOT thread safe, as explained in https://open.nytimes.com/the-future-of-meta-tag-management-for-modern-react-development-ec26a7dc9183#fdc2

Therefore, it's better if react-helmet-async is utilized instead of react-helmet.

Even though react-helmet-async is being utilized, most users will not require any code changes to @docusaurus/Head since it uses the same API as react-helmet.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

* Include HelmetProvider inside client entry

I forgot to do this before.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

* format

* fix TS

* address reviews

* Remove forked react-loadable package in favor of @react-loadable/revised

Both unforked react-loadable and @docusaurus/react-loadable uses legacy React APIs.

However, @react-loadable/revised (https://github.com/react-loadable/revised) is actively maintained and widely used in production, thus replaced with this package.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

* remove unused comma

* Address reviews from #6306 (review)

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

Co-authored-by: Joshua Chen <[email protected]>

Include HelmetProvider inside client entry

I forgot to do this before.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

fix TS

address reviews

Remove forked react-loadable package in favor of @react-loadable/revised

Both unforked react-loadable and @docusaurus/react-loadable uses legacy React APIs.

However, @react-loadable/revised (https://github.com/react-loadable/revised) is actively maintained and widely used in production, thus replaced with this package.

Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>

remove unused comma
Josh-Cena pushed a commit that referenced this pull request Feb 2, 2022
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Josh-Cena pushed a commit that referenced this pull request Feb 2, 2022
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Signed Facebook CLA pr: polish This PR adds a very minor behavior improvement that users will enjoy.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants