From 3a6b86c02b5c196c8832dcc72ce9f0c1f557dee0 Mon Sep 17 00:00:00 2001 From: Arvin Xu Date: Sun, 29 Sep 2024 00:24:31 +0800 Subject: [PATCH] :sparkles: feat: remove `@emotion/server` to adapt SSR in edge runtime (#169) --- CHANGELOG.md | 6 +++ package.json | 13 +++-- src/functions/extractStaticStyle.tsx | 6 ++- src/utils/createEmotionServer/index.ts | 49 +++++++++++++++++++ .../createInstance.test.tsx.snap | 2 +- .../__snapshots__/createStyles.test.tsx.snap | 2 +- 6 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 src/utils/createEmotionServer/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 025f0ee9..6033763e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +# [3.7.0-beta.1](https://github.com/ant-design/antd-style/compare/v3.6.3...v3.7.0-beta.1) (2024-09-27) + +### ✨ Features + +- Try to remove @emotion/server to suit SSR in edge runtime ([a7d0394](https://github.com/ant-design/antd-style/commit/a7d0394)) + ## [3.6.3](https://github.com/ant-design/antd-style/compare/v3.6.2...v3.6.3) (2024-09-12) ### 🐛 Bug Fixes diff --git a/package.json b/package.json index 41bff5ab..749a45ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd-style", - "version": "3.6.3", + "version": "3.7.0-beta.1", "description": "css-in-js solution for application combine with antd v5 token system and emotion", "keywords": [ "antd", @@ -69,18 +69,17 @@ ] }, "dependencies": { - "@ant-design/cssinjs": "^1.18.5", + "@ant-design/cssinjs": "^1.21.1", "@babel/runtime": "^7.24.1", "@emotion/cache": "^11.11.0", "@emotion/css": "^11.11.2", "@emotion/react": "^11.11.4", "@emotion/serialize": "^1.1.3", - "@emotion/server": "^11.11.0", "@emotion/utils": "^1.2.1", "use-merge-value": "^1.2.0" }, "devDependencies": { - "@ant-design/icons": "^5.3.5", + "@ant-design/icons": "^5.5.1", "@commitlint/cli": "^17.8.1", "@emotion/jest": "^11.11.0", "@emotion/styled": "^11.11.0", @@ -97,7 +96,7 @@ "@types/testing-library__jest-dom": "^5.14.9", "@umijs/lint": "^4.1.5", "@vitest/coverage-v8": "0.34.6", - "antd": "^5.15.3", + "antd": "^5.21.1", "babel-plugin-antd-style": "^1.0.4", "chalk": "^4.1.2", "classnames": "^2.5.1", @@ -105,8 +104,8 @@ "commitlint-config-gitmoji": "^2.3.1", "concurrently": "^7.6.0", "cross-env": "^7.0.3", - "dumi": "^2.2.17", - "dumi-theme-antd-style": "latest", + "dumi": "^2.4.12", + "dumi-theme-antd-style": "^0.31.1", "eslint": "^8.57.0", "father": "^4.4.0", "framer-motion": "^8.5.5", diff --git a/src/functions/extractStaticStyle.tsx b/src/functions/extractStaticStyle.tsx index 7812dd56..592ce280 100644 --- a/src/functions/extractStaticStyle.tsx +++ b/src/functions/extractStaticStyle.tsx @@ -3,6 +3,8 @@ import CacheEntity from '@ant-design/cssinjs/es/Cache'; import { EmotionCache } from '@emotion/css/create-instance'; import { version } from 'antd'; +import { createExtractCritical } from '@/utils/createEmotionServer'; + const createExtractCriticalWithoutHtml = (cache: EmotionCache) => ({ ids: Object.keys(cache.inserted), css: Object.values(cache.inserted) @@ -81,11 +83,11 @@ export const extractStaticStyle = (html?: string, options?: ExtractStyleOptions) // copy from emotion ssr // https://github.com/vercel/next.js/blob/deprecated-main/examples/with-emotion-vanilla/pages/_document.js const styles = global.__ANTD_STYLE_CACHE_MANAGER_FOR_SSR__.getCacheList().map((cache) => { - const createEmotionServer = require('@emotion/server/create-instance').default; + const extractHtml = createExtractCritical(cache); const result: { ids: string[]; css: string } = !html ? createExtractCriticalWithoutHtml(cache) - : createEmotionServer(cache).extractCritical(html); + : extractHtml(html); if (!result.css) return null; diff --git a/src/utils/createEmotionServer/index.ts b/src/utils/createEmotionServer/index.ts new file mode 100644 index 00000000..4ae5e93b --- /dev/null +++ b/src/utils/createEmotionServer/index.ts @@ -0,0 +1,49 @@ +// copy from +// https://github.com/emotion-js/emotion/blob/main/packages/server/src/create-instance/extract-critical.js + +import { EmotionCache } from '@emotion/utils'; + +export const createExtractCritical = (cache: EmotionCache) => { + if (cache.compat !== true) { + // is this good? should we do this automatically? + // this is only for when using the new apis (not emotion or create-emotion) + cache.compat = true; + } + + return (html: string) => { + // parse out ids from html + // reconstruct css/rules/cache to pass + let RGX = new RegExp(cache.key + '-([a-zA-Z0-9-_]+)', 'gm'); + let o: { + html: string; + ids: string[]; + css: string; + } = { + html: html, + ids: [], + css: '', + }; + let match; + let ids: Record = {}; + + while ((match = RGX.exec(html)) !== null) { + if (ids[match[1]] === undefined) { + ids[match[1]] = true; + } + } + + o.ids = Object.keys(cache.inserted).filter((id) => { + if ( + (ids[id] !== undefined || cache.registered[cache.key + '-' + id] === undefined) && + cache.inserted[id] !== true + ) { + o.css += cache.inserted[id]; + return true; + } + + return false; + }); + + return o; + }; +}; diff --git a/tests/functions/__snapshots__/createInstance.test.tsx.snap b/tests/functions/__snapshots__/createInstance.test.tsx.snap index 55b4569d..e32c2318 100644 --- a/tests/functions/__snapshots__/createInstance.test.tsx.snap +++ b/tests/functions/__snapshots__/createInstance.test.tsx.snap @@ -12,7 +12,7 @@ exports[`createInstance > 自定义 prefixCls 时,会采用 instance 的 prefi }