From be3638ecf8065bfa441b6a27d0efba9be8a4f279 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sat, 25 Mar 2023 17:42:11 +0530 Subject: [PATCH 1/6] removed styled component and setup-ed emotion --- next.config.js | 6 - package.json | 12 +- src/pages/_app.tsx | 24 +- src/pages/_document.tsx | 166 ++++++---- src/themes/createEmotionCache.ts | 19 ++ tsconfig.json | 6 +- yarn.lock | 549 +++++++++++++++++++++++-------- 7 files changed, 558 insertions(+), 224 deletions(-) create mode 100644 src/themes/createEmotionCache.ts diff --git a/next.config.js b/next.config.js index 4a46dcfac4..601f9534d1 100644 --- a/next.config.js +++ b/next.config.js @@ -28,12 +28,6 @@ module.exports = (phase) => '@mui/system', '@mui/icons-material', ], - compiler: { - styledComponents: { - ssr: true, - displayName: true, - }, - }, env: { SENTRY_RELEASE: GIT_SHA, NEXT_PUBLIC_IS_TEST_APP: process.env.IS_TEST_RELEASE, diff --git a/package.json b/package.json index 7ecf044254..1c0f6b84e6 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,12 @@ }, "dependencies": { "@date-io/date-fns": "^2.14.0", + "@emotion/cache": "^11.10.5", + "@emotion/react": "^11.10.6", + "@emotion/server": "^11.10.0", + "@emotion/styled": "^11.10.6", "@mui/icons-material": "^5.6.2", "@mui/material": "^5.6.2", - "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest", - "@mui/styled-engine-sc": "^5.6.1", "@mui/x-date-pickers": "^5.0.0-alpha.6", "@sentry/nextjs": "^6.7.1", "@stripe/stripe-js": "^1.13.2", @@ -97,7 +99,6 @@ "@types/react-select": "^4.0.15", "@types/react-window": "^1.8.2", "@types/react-window-infinite-loader": "^1.0.3", - "@types/styled-components": "^5.1.25", "@types/wicg-file-system-access": "^2020.9.5", "@types/yup": "^0.29.7", "@types/zxcvbn": "^4.4.1", @@ -112,8 +113,5 @@ }, "standard": { "parser": "babel-eslint" - }, - "resolutions": { - "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest" } -} +} \ No newline at end of file diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index a9d68dcdc6..45bea454ad 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -26,7 +26,6 @@ import darkThemeOptions from 'themes/darkThemeOptions'; import lightThemeOptions from 'themes/lightThemeOptions'; import { CssBaseline, useMediaQuery } from '@mui/material'; // eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as types from 'styled-components/cssprop'; // need to css prop on styled component import { SetDialogBoxAttributes, DialogBoxAttributes } from 'types/dialogBox'; import { getFamilyPortalRedirectURL, @@ -56,6 +55,9 @@ import { SetTheme } from 'types/theme'; import { useLocalState } from 'hooks/useLocalState'; import { THEME_COLOR } from 'constants/theme'; import { setupI18n } from 'i18n'; +import createEmotionCache from 'themes/createEmotionCache'; +import { CacheProvider, EmotionCache } from '@emotion/react'; +import { AppProps } from 'next/app'; export const MessageContainer = styled('div')` background-color: #111; @@ -115,7 +117,19 @@ const redirectMap = new Map([ const APP_TITLE = 'ente Photos'; -export default function App({ Component, err }) { +// Client-side cache, shared for the whole session of the user in the browser. +const clientSideEmotionCache = createEmotionCache(); + +export interface MyAppProps extends AppProps { + emotionCache?: EmotionCache; +} + +export default function App(props) { + const { + Component, + emotionCache = clientSideEmotionCache, + pageProps, + } = props; const router = useRouter(); const [isI18nReady, setIsI18nReady] = useState(false); const [loading, setLoading] = useState(false); @@ -323,7 +337,7 @@ export default function App({ Component, err }) { }); return ( - <> + {isI18nReady ? t('TITLE') : APP_TITLE} ) : ( - + )} - + ); } diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 21fc9bdd82..79929d605d 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -1,66 +1,110 @@ import React from 'react'; -import Document, { Html, Head, Main, NextScript } from 'next/document'; -import { ServerStyleSheet } from 'styled-components'; +import Document, { + Html, + Head, + Main, + NextScript, + DocumentProps, + DocumentContext, +} from 'next/document'; -export default class MyDocument extends Document { - static async getInitialProps(ctx) { - const sheet = new ServerStyleSheet(); - const originalRenderPage = ctx.renderPage; +import createEmotionServer from '@emotion/server/create-instance'; +import { AppType } from 'next/app'; +import createEmotionCache from 'themes/createEmotionCache'; +import { MyAppProps } from './_app'; - try { - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: (App) => (props) => - sheet.collectStyles(), - }); - - const initialProps = await Document.getInitialProps(ctx); - return { - ...initialProps, - styles: ( - <> - {initialProps.styles} - {sheet.getStyleElement()} - - ), - }; - } finally { - sheet.seal(); - } - } +interface MyDocumentProps extends DocumentProps { + emotionStyleTags: JSX.Element[]; +} - render() { - return ( - - - - - - - - - - - - -
- - - - ); - } +export default function MyDocument({ emotionStyleTags }: MyDocumentProps) { + return ( + + + + + + + + + + + {emotionStyleTags} + + +
+ + + + ); } + +// `getInitialProps` belongs to `_document` (instead of `_app`), +// it's compatible with static-site generation (SSG). +MyDocument.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 & MyAppProps + > + ) => + function EnhanceApp(props) { + return ; + }, + }); + + 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) => ( +