From 0cd18378366b3645919795f2e41bd175a54e5788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=8C=AF=E6=B4=AA?= <2976151305@qq.com> Date: Thu, 4 Jan 2024 17:02:06 +0800 Subject: [PATCH] feat: antd first-screen style loading --- web/genAntdCss.ts | 36 +++++++++++++++++++++++++++ web/pages/_document.tsx | 43 +++++++++++++++++++++++++++++++-- web/pages/chat/[scene]/[id].tsx | 27 --------------------- 3 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 web/genAntdCss.ts delete mode 100644 web/pages/chat/[scene]/[id].tsx diff --git a/web/genAntdCss.ts b/web/genAntdCss.ts new file mode 100644 index 000000000..ac1ff3663 --- /dev/null +++ b/web/genAntdCss.ts @@ -0,0 +1,36 @@ +import { createHash } from 'crypto'; +import fs from 'fs'; +import path from 'path'; +import { extractStyle } from '@ant-design/cssinjs'; +import type Entity from '@ant-design/cssinjs/lib/Cache'; + +export type DoExtraStyleOptions = { + cache: Entity; + dir?: string; + baseFileName?: string; +}; +export function doExtraStyle({ cache, dir = 'antd-output', baseFileName = 'antd.min' }: DoExtraStyleOptions) { + const baseDir = path.resolve(__dirname, '../../static/css'); + + const outputCssPath = path.join(baseDir, dir); + + if (!fs.existsSync(outputCssPath)) { + fs.mkdirSync(outputCssPath, { recursive: true }); + } + + const css = extractStyle(cache, true); + if (!css) return ''; + + const md5 = createHash('md5'); + const hash = md5.update(css).digest('hex'); + const fileName = `${baseFileName}.${hash.substring(0, 8)}.css`; + const fullpath = path.join(outputCssPath, fileName); + + const res = `_next/static/css/${dir}/${fileName}`; + + if (fs.existsSync(fullpath)) return res; + + fs.writeFileSync(fullpath, css); + + return res; +} diff --git a/web/pages/_document.tsx b/web/pages/_document.tsx index 6deb2b934..01ca34b98 100644 --- a/web/pages/_document.tsx +++ b/web/pages/_document.tsx @@ -1,6 +1,45 @@ -import Document, { Head, Html, Main, NextScript } from 'next/document'; +import { createCache, StyleProvider } from '@ant-design/cssinjs'; +import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document'; +import { doExtraStyle } from '../genAntdCss'; + +interface Props { + currentUrl: string; +} + +class MyDocument extends Document { + static async getInitialProps(ctx: DocumentContext) { + const cache = createCache(); + let fileName = ''; + const originalRenderPage = ctx.renderPage; + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => (props) => + ( + + + + ), + }); + const initialProps = await Document.getInitialProps(ctx); + const currentUrl = ctx.req?.url; + + fileName = doExtraStyle({ + cache, + }); + + return { + ...initialProps, + currentUrl, + styles: ( + <> + {initialProps.styles} + {/* 1.2 inject css */} + {fileName && } + + ), + }; + } -class MyDocument extends Document { render() { return ( diff --git a/web/pages/chat/[scene]/[id].tsx b/web/pages/chat/[scene]/[id].tsx deleted file mode 100644 index 6d7891298..000000000 --- a/web/pages/chat/[scene]/[id].tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { useContext, useEffect } from 'react'; -import { useRouter } from 'next/router'; -import { ChatContext } from '@/app/chat-context'; -import dynamic from 'next/dynamic'; - -const DbEditor = dynamic(() => import('@/components/chat/db-editor'), { ssr: false }); -const ChatContainer = dynamic(() => import('@/components/chat/chat-container'), { ssr: false }); - -function Chat() { - const { - query: { id, scene }, - } = useRouter(); - const { isContract, setIsContract, setIsMenuExpand } = useContext(ChatContext); - - useEffect(() => { - // 仅初始化执行,防止dashboard页面无法切换状态 - setIsMenuExpand(scene !== 'chat_dashboard'); - // 路由变了要取消Editor模式,再进来是默认的Preview模式 - if (id && scene) { - setIsContract(false); - } - }, [id, scene]); - - return <>{isContract ? : }; -} - -export default Chat;