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

refactor: fix the SSR/CSR mismatch #146

Merged
merged 10 commits into from
Sep 13, 2024

Conversation

HsiangNianian
Copy link
Contributor

@HsiangNianian HsiangNianian commented Sep 11, 2024

What happened?

Due to the CSS not being written in a format supported by Webpack1, I imported postcss-preset-env(a10ec67) and created the customPostCssPlugin function(091a16f) (the code is provided below) to enable runtime plugins, achieving the goal of using preset environment CSS. This has clearly been effective.

function customPostCssPlugin() {
  return {
    name: "custom-postcss",
    configurePostCss(options) {
      // Append new PostCSS plugins here
      options.plugins.push(require("postcss-preset-env")); // allow newest CSS syntax
      return options;
    }
  };
}

The Changes

Important

There is one remaining warning, similar to the previous ones.
This final error is still due to the CSS format, but it cannot be detected by the customPostCssPlugin.

image before
image after

So you can continue to make modifications from this perspective to try to get the compilation build workflow to pass. Since it's already quite late (USTC +8), I currently don't have the ability to further investigate any suspicious CSS syntax.

This is the everything about WA.


Literally, I noticed the error about useColorMode() in prod mode. Values derived from useColorMode() can be stale when rendering in prod mode, so we have to avoid to use import { useColorMode } from '@docusaurus/theme-common'; and this is likely a react hydration problem.

const getInitialColorMode = (defaultMode: ColorMode | undefined): ColorMode =>
  ExecutionEnvironment.canUseDOM
    ? coerceToColorMode(document.documentElement.getAttribute('data-theme'))
    : coerceToColorMode(defaultMode);

  const [colorMode, setColorModeState] = useState(
    getInitialColorMode(defaultMode),
  );

Asfaik, react 18 introduces a onRecoverableError callback which usually notice you of hydration mismatches.

In this case we can't technically init react state with the correct value, but instead should always init it to the default color mode, and then trigger a new re-render to fix it after hydration.

const [colorMode, setColorModeState] = useState(defaultMode);

useLayoutEffect(() => {
  coerceToColorMode(document.documentElement.getAttribute('data-theme'))
},[])

This should fix the SSR/CSR mismatch, but this is a bit annoying unfortunately, as it will mean some components will render first with the wrong colorMode and then eventually re-render with the right one.

Footnotes

  1. https://github.com/webpack/webpack/issues/14893

Copy link

vercel bot commented Sep 11, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
farm-fe-github-io ❌ Failed (Inspect) Sep 12, 2024 5:47am

@HsiangNianian HsiangNianian marked this pull request as draft September 11, 2024 15:23
@HsiangNianian HsiangNianian changed the title chore(ci): add manually active test deploy event in test-deploy.yml fix: help to avoid build error Sep 11, 2024
@wre232114
Copy link
Member

Thanks!

@HsiangNianian HsiangNianian changed the title fix: help to avoid build error refactor: fix the SSR/CSR mismatch Sep 12, 2024
@HsiangNianian
Copy link
Contributor Author

HsiangNianian commented Sep 12, 2024

Alternatively, you could use themed-images, which might be the best solution aside from the aforementioned approaches and using:

// You might be fine with the following, but use at your own risks, 
// and be aware it is likely to create issues down the line
const isDarkMode = document.documentElement.getAttribute('data-theme') === "dark";

Docusaurus doesn't have good support for "legacy CSS-in-JS libs" (StyledComponents, Emotion, JSS, MUI...), that require collecting styles during the rendering process (see also facebook/docusaurus#3236).

Warning

However, you may have noticed that ThemedImage seems to only support file-based resources, rather than components like <StarrySky /> or <AuroraBackground />. After modifying it(see also 3ec0863), I was able to get it to build, but the background does not display correctly.


The Lives

image light
image dark

Copy link
Contributor Author

@HsiangNianian HsiangNianian left a comment

Choose a reason for hiding this comment

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

Even though the compilation build workflow is successful, the actual effect is still problematic(see also #146 (comment))

@fu050409
Copy link
Member

fu050409 commented Sep 12, 2024

Thanks for your work :)

@ErKeLost take a look?

@ErKeLost
Copy link
Member

ErKeLost commented Sep 13, 2024

@HsiangNianian thank you for your work,I will try to repair the next work

@ErKeLost ErKeLost merged commit 76faaca into farm-fe:main Sep 13, 2024
3 of 4 checks passed
@HsiangNianian HsiangNianian deleted the fix-build-error branch September 13, 2024 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants