Browse Source

[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.
Manav Rathi 1 year ago
parent
commit
7183a8b493

+ 5 - 14
web/apps/accounts/src/pages/_app.tsx

@@ -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>
+        </>
     );
 }

+ 2 - 6
web/apps/accounts/src/pages/_document.tsx

@@ -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;

+ 19 - 30
web/apps/auth/src/pages/_app.tsx

@@ -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 { getTheme } from "@ente/shared/themes";
+import { THEME_COLOR } from "@ente/shared/themes/constants";
+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 { 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 "../../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>
+        </>
     );
 }

+ 2 - 6
web/apps/auth/src/pages/_document.tsx

@@ -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;

+ 11 - 21
web/apps/photos/src/pages/_app.tsx

@@ -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>
+        </>
     );
 }

+ 2 - 6
web/apps/photos/src/pages/_document.tsx

@@ -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;

+ 0 - 6
web/packages/shared/apps/types.ts

@@ -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;

+ 2 - 84
web/packages/shared/next/pages/_document.tsx

@@ -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,
-    };
-};

+ 0 - 19
web/packages/shared/themes/createEmotionCache.ts

@@ -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 });
-}