[web] Remove emotion caches

This is no longer needed for emotion > 10

> For v10 and above, SSR just works in Next.js.
>
> https://emotion.sh/docs/ssr#nextjs

Tested with

- yarn dev:*
- yarn preview:*

This change screws up the CSS in places in dev mode though.
This commit is contained in:
Manav Rathi 2024-03-30 17:17:25 +05:30
parent 5810d2b762
commit 7183a8b493
No known key found for this signature in database
9 changed files with 45 additions and 194 deletions

View file

@ -1,7 +1,5 @@
import { setupI18n } from "@/ui/i18n";
import { CacheProvider } from "@emotion/react";
import { APPS, APP_TITLES } from "@ente/shared/apps/constants";
import { EnteAppProps } from "@ente/shared/apps/types";
import { Overlay } from "@ente/shared/components/Container";
import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
import {
@ -15,9 +13,9 @@ import HTTPService from "@ente/shared/network/HTTPService";
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
import { getTheme } from "@ente/shared/themes";
import { THEME_COLOR } from "@ente/shared/themes/constants";
import createEmotionCache from "@ente/shared/themes/createEmotionCache";
import { CssBaseline, useMediaQuery } from "@mui/material";
import { ThemeProvider } from "@mui/material/styles";
import { AppProps } from "next/app";
import Head from "next/head";
import { useRouter } from "next/router";
import { createContext, useEffect, useState } from "react";
@ -31,10 +29,7 @@ interface AppContextProps {
export const AppContext = createContext<AppContextProps>({} as AppContextProps);
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
export default function App(props: EnteAppProps) {
export default function App(props: AppProps) {
const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
const [showNavbar, setShowNavBar] = useState(false);
@ -54,11 +49,7 @@ export default function App(props: EnteAppProps) {
const router = useRouter();
const {
Component,
emotionCache = clientSideEmotionCache,
pageProps,
} = props;
const { Component, pageProps } = props;
const [themeColor] = useLocalState(LS_KEYS.THEME, THEME_COLOR.DARK);
@ -87,7 +78,7 @@ export default function App(props: EnteAppProps) {
// TODO: Localise APP_TITLES
return (
<CacheProvider value={emotionCache}>
<>
<Head>
<title>{APP_TITLES.get(APPS.ACCOUNTS)}</title>
<meta
@ -131,6 +122,6 @@ export default function App(props: EnteAppProps) {
{isI18nReady && <Component {...pageProps} />}
</AppContext.Provider>
</ThemeProvider>
</CacheProvider>
</>
);
}

View file

@ -1,7 +1,3 @@
import DocumentPage, {
EnteDocumentProps,
} from "@ente/shared/next/pages/_document";
import DocumentPage from "@ente/shared/next/pages/_document";
export default function Document(props: EnteDocumentProps) {
return <DocumentPage {...props} />;
}
export default DocumentPage;

View file

@ -1,7 +1,9 @@
import AppNavbar from "@ente/shared/components/Navbar/app";
import { t } from "i18next";
import { createContext, useEffect, useRef, useState } from "react";
import { setupI18n } from "@/ui/i18n";
import {
APPS,
APP_TITLES,
CLIENT_PACKAGE_NAMES,
} from "@ente/shared/apps/constants";
import { Overlay } from "@ente/shared/components/Container";
import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
import {
@ -10,32 +12,26 @@ import {
} from "@ente/shared/components/DialogBoxV2/types";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
import { MessageContainer } from "@ente/shared/components/MessageContainer";
import AppNavbar from "@ente/shared/components/Navbar/app";
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
import { useLocalState } from "@ente/shared/hooks/useLocalState";
import {
clearLogsIfLocalStorageLimitExceeded,
logStartupMessage,
} from "@ente/shared/logging/web";
import HTTPService from "@ente/shared/network/HTTPService";
import { LS_KEYS } from "@ente/shared/storage/localStorage";
import { CssBaseline, useMediaQuery } from "@mui/material";
import { ThemeProvider } from "@mui/material/styles";
import Head from "next/head";
import { useRouter } from "next/router";
import LoadingBar from "react-top-loading-bar";
import { setupI18n } from "@/ui/i18n";
import { CacheProvider } from "@emotion/react";
import {
APP_TITLES,
APPS,
CLIENT_PACKAGE_NAMES,
} from "@ente/shared/apps/constants";
import { EnteAppProps } from "@ente/shared/apps/types";
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
import { useLocalState } from "@ente/shared/hooks/useLocalState";
import { getTheme } from "@ente/shared/themes";
import { THEME_COLOR } from "@ente/shared/themes/constants";
import createEmotionCache from "@ente/shared/themes/createEmotionCache";
import { SetTheme } from "@ente/shared/themes/types";
import { CssBaseline, useMediaQuery } from "@mui/material";
import { ThemeProvider } from "@mui/material/styles";
import { t } from "i18next";
import { AppProps } from "next/app";
import Head from "next/head";
import { useRouter } from "next/router";
import { createContext, useEffect, useRef, useState } from "react";
import LoadingBar from "react-top-loading-bar";
import "../../public/css/global.css";
type AppContextType = {
@ -51,15 +47,8 @@ type AppContextType = {
export const AppContext = createContext<AppContextType>(null);
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
export default function App(props: EnteAppProps) {
const {
Component,
emotionCache = clientSideEmotionCache,
pageProps,
} = props;
export default function App(props: AppProps) {
const { Component, pageProps } = props;
const router = useRouter();
const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
const [loading, setLoading] = useState(false);
@ -141,7 +130,7 @@ export default function App(props: EnteAppProps) {
});
return (
<CacheProvider value={emotionCache}>
<>
<Head>
<title>
{isI18nReady
@ -200,6 +189,6 @@ export default function App(props: EnteAppProps) {
)}
</AppContext.Provider>
</ThemeProvider>
</CacheProvider>
</>
);
}

View file

@ -1,7 +1,3 @@
import DocumentPage, {
EnteDocumentProps,
} from "@ente/shared/next/pages/_document";
import DocumentPage from "@ente/shared/next/pages/_document";
export default function Document(props: EnteDocumentProps) {
return <DocumentPage {...props} />;
}
export default DocumentPage;

View file

@ -1,15 +1,9 @@
import AppNavbar from "@ente/shared/components/Navbar/app";
import { t } from "i18next";
import { createContext, useEffect, useRef, useState } from "react";
import { setupI18n } from "@/ui/i18n";
import { CacheProvider } from "@emotion/react";
import {
APP_TITLES,
APPS,
APP_TITLES,
CLIENT_PACKAGE_NAMES,
} from "@ente/shared/apps/constants";
import { EnteAppProps } from "@ente/shared/apps/types";
import { Overlay } from "@ente/shared/components/Container";
import DialogBox from "@ente/shared/components/DialogBox";
import {
@ -23,11 +17,12 @@ import {
} from "@ente/shared/components/DialogBoxV2/types";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
import { MessageContainer } from "@ente/shared/components/MessageContainer";
import AppNavbar from "@ente/shared/components/Navbar/app";
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
import ElectronAPIs from "@ente/shared/electron";
import { AppUpdateInfo } from "@ente/shared/electron/types";
import { CustomError } from "@ente/shared/error";
import { eventBus, Events } from "@ente/shared/events";
import { Events, eventBus } from "@ente/shared/events";
import { useLocalState } from "@ente/shared/hooks/useLocalState";
import { addLogLine } from "@ente/shared/logging";
import {
@ -36,7 +31,7 @@ import {
} from "@ente/shared/logging/web";
import HTTPService from "@ente/shared/network/HTTPService";
import { logError } from "@ente/shared/sentry";
import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
import {
getLocalMapEnabled,
getToken,
@ -44,7 +39,6 @@ import {
} from "@ente/shared/storage/localStorage/helpers";
import { getTheme } from "@ente/shared/themes";
import { THEME_COLOR } from "@ente/shared/themes/constants";
import createEmotionCache from "@ente/shared/themes/createEmotionCache";
import { SetTheme } from "@ente/shared/themes/types";
import ArrowForward from "@mui/icons-material/ArrowForward";
import { CssBaseline, useMediaQuery } from "@mui/material";
@ -52,10 +46,13 @@ import { ThemeProvider } from "@mui/material/styles";
import "bootstrap/dist/css/bootstrap.min.css";
import Notification from "components/Notification";
import { REDIRECTS } from "constants/redirects";
import { t } from "i18next";
import isElectron from "is-electron";
import { AppProps } from "next/app";
import Head from "next/head";
import { useRouter } from "next/router";
import "photoswipe/dist/photoswipe.css";
import { createContext, useEffect, useRef, useState } from "react";
import LoadingBar from "react-top-loading-bar";
import DownloadManager from "services/download";
import exportService from "services/export";
@ -115,15 +112,8 @@ type AppContextType = {
export const AppContext = createContext<AppContextType>(null);
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
export default function App(props: EnteAppProps) {
const {
Component,
emotionCache = clientSideEmotionCache,
pageProps,
} = props;
export default function App(props: AppProps) {
const { Component, pageProps } = props;
const router = useRouter();
const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
const [loading, setLoading] = useState(false);
@ -390,7 +380,7 @@ export default function App(props: EnteAppProps) {
});
return (
<CacheProvider value={emotionCache}>
<>
<Head>
<title>
{isI18nReady
@ -491,6 +481,6 @@ export default function App(props: EnteAppProps) {
)}
</AppContext.Provider>
</ThemeProvider>
</CacheProvider>
</>
);
}

View file

@ -1,7 +1,3 @@
import DocumentPage, {
EnteDocumentProps,
} from "@ente/shared/next/pages/_document";
import DocumentPage from "@ente/shared/next/pages/_document";
export default function Document(props: EnteDocumentProps) {
return <DocumentPage {...props} />;
}
export default DocumentPage;

View file

@ -1,14 +1,8 @@
import { EmotionCache } from "@emotion/react";
import { TwoFactorType } from "@ente/accounts/constants/twofactor";
import { SetDialogBoxAttributesV2 } from "@ente/shared/components/DialogBoxV2/types";
import { AppProps } from "next/app";
import { NextRouter } from "next/router";
import { APPS } from "./constants";
export interface EnteAppProps extends AppProps {
emotionCache?: EmotionCache;
}
export interface PageProps {
appContext: {
showNavBar: (show: boolean) => void;

View file

@ -1,23 +1,6 @@
import Document, {
DocumentContext,
DocumentProps,
Head,
Html,
Main,
NextScript,
} from "next/document";
import React from "react";
import { Head, Html, Main, NextScript } from "next/document";
import createEmotionServer from "@emotion/server/create-instance";
import { EnteAppProps } from "@ente/shared/apps/types";
import createEmotionCache from "@ente/shared/themes/createEmotionCache";
import { AppType } from "next/app";
export interface EnteDocumentProps extends DocumentProps {
emotionStyleTags: JSX.Element[];
}
export default function EnteDocument({ emotionStyleTags }: EnteDocumentProps) {
export default function EnteDocument() {
return (
<Html lang="en">
<Head>
@ -27,7 +10,6 @@ export default function EnteDocument({ emotionStyleTags }: EnteDocumentProps) {
/>
<link rel="icon" href="/images/favicon.png" type="image/png" />
<meta name="apple-mobile-web-app-capable" content="yes" />
{emotionStyleTags}
</Head>
<body>
<Main />
@ -36,67 +18,3 @@ export default function EnteDocument({ emotionStyleTags }: EnteDocumentProps) {
</Html>
);
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with static-site generation (SSG).
EnteDocument.getInitialProps = async (ctx: DocumentContext) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
const originalRenderPage = ctx.renderPage;
// You can consider sharing the same Emotion cache between all the SSR requests to speed up performance.
// However, be aware that it can have global side effects.
const cache = createEmotionCache();
// eslint-disable-next-line @typescript-eslint/unbound-method
const { extractCriticalToChunks } = createEmotionServer(cache);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (
App: React.ComponentType<
React.ComponentProps<AppType> & EnteAppProps
>,
) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />;
},
});
const initialProps = await Document.getInitialProps(ctx);
// This is important. It prevents Emotion to render invalid HTML.
// See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html);
const emotionStyleTags = emotionStyles.styles.map((style) => (
<style
data-emotion={`${style.key} ${style.ids.join(" ")}`}
key={style.key}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.css }}
/>
));
return {
...initialProps,
emotionStyleTags,
};
};

View file

@ -1,19 +0,0 @@
import createCache from "@emotion/cache";
const isBrowser = typeof document !== "undefined";
// On the client side, Create a meta tag at the top of the <head> and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
let insertionPoint;
if (isBrowser) {
const emotionInsertionPoint = document.querySelector<HTMLMetaElement>(
'meta[name="emotion-insertion-point"]',
);
insertionPoint = emotionInsertionPoint ?? undefined;
}
return createCache({ key: "mui-style", insertionPoint });
}