- CMS
- 后端
- 前端
【免费下载链接】webiny-js
Open-source, self-hosted CMS platform on AWS serverless (Lambda, DynamoDB, S3). TypeScript framework with multi-tenancy, lifecycle hooks, GraphQL API, and AI-assisted development via MCP server. Built for developers at large organizations.
Webiny 是一个基于 AWS Serverless(Lambda、DynamoDB、S3)构建的开源自托管 CMS 平台,其管理端与应用端由大量 React 包组成。本文以仓库内 dependencies/react.md 这份依赖审计清单为骨架,逐项解读每个 React 相关依赖的现状(Status: ok / replace / reduce)、被替代原因与推荐替代方案,并结合packages/*中各包的package.json与核心源码验证实际使用情况。读完本文,你将获得一份可直接指导依赖瘦身、技术栈现代化与迁移排期的实战清单。
一、审计背景:React 18.3.1 与"替代还是保留"的决策框架
这份文档本质上是一份依赖健康度审计表,目标是在不破坏现有功能的前提下,逐步清理长期无人维护(unmaintained)的 React 生态依赖,同时优先复用仓库中"已经在依赖里"的现代替代品,最终达到降低包体积、减少运行时开销、降低维护风险的效果。
审计状态分为三档:
| 状态 | 含义 | 处理策略 |
|---|---|---|
ok | 依赖健康、仍在维护,或与现有架构深度绑定 | 保留,暂不动作 |
replace | 依赖长期失维护,或与现有技术栈重叠冗余 | 制定迁移计划,替换为现代替代方案 |
reduce | 功能与现有依赖重叠,可能冗余 | 评估后缩减或移除 |
从根目录 package.json 可以看到,整个 monorepo 通过resolutions强制锁定了react、react-dom为18.3.1,@types/react为18.3.31、@types/react-dom为18.3.7,与文档所述 "Currently 18.3.1" 完全一致;React 19 已发布,文档将其标记为"待迁移"(React 19 is available when ready to migrate)。
二、核心运行时:react / react-dom —— 现状 OK,React 19 迁移窗口已打开
## react, react-dom Status: ok Currently 18.3.1. React 19 is available when ready to migrate.结论:保留,但需要规划 React 19 升级。
- 全仓库各前端包(如 packages/app-admin/package.json、packages/admin-ui/package.json)均声明
react: 18.3.1、react-dom: 18.3.1,根resolutions亦将其固定,保证所有 workspace 包共享同一 React 版本。 - React 19 的核心变化包括:
ref作为普通 prop 传递、<Context>直接作为 Provider、删除forwardRef的强制要求等。迁移前需重点审计仓库内对forwardRef、ReactDOM.render等旧 API 的使用,以及第三方依赖(如react-transition-group、react-virtualized)的 React 19 兼容性——这恰是下文"replace"清单要优先解决的问题。
迁移建议:先完成本文第三部分的"replace"替换,再升级 React 19,可最大程度降低一次性迁移风险。
三、需替换(replace)的依赖:失维护包与现代化替代方案
3.1 react-helmet → react-helmet-async(文档管理)
Status: replace Unmaintained since 2020. Use `react-helmet-async` (drop-in, maintained).react-helmet自 2020 年起停止维护,而仓库中仍有多处直接使用:packages/app-admin/package.json、packages/app-workflows/package.json、packages/app-admin-ui/package.json、packages/app-headless-cms/package.json、packages/app-website-builder-workflows/package.json等均声明了react-helmet: ^6.1.0。
替代方案react-helmet-async是官方推荐的 drop-in 替代,API 几乎一致(<Helmet>组件),并额外支持并发渲染场景(如 React 18 的流式渲染与 SSR)下的文档管理安全。迁移时可保留现有<Helmet>用法,仅将 import 路径从react-helmet改为react-helmet-async。
3.2 react-color → react-colorful(颜色选择器)
Status: replace Unmaintained since 2020. Use `react-colorful` (smaller, maintained, hooks-based).react-color同样自 2020 年失维护,仓库中 packages/admin-ui/package.json 声明了react-color: ^2.19.3(以及@types/react-color: ^3.0.13),典型使用场景是管理后台中的颜色选择控件。
react-colorful的优势:
- 体积远小于
react-color(约 2KB vs 数十 KB,含样式零依赖); - 基于 hooks,API 更现代:
<HexColorPicker color={...} onChange={...}>; - 持续维护,TypeScript 原生支持,可移除
@types/react-color这个额外的类型包。
3.3 react-custom-scrollbars → @radix-ui/react-scroll-area 或原生 CSS(滚动区域)
Status: replace Unmaintained since 2017. Use `@radix-ui/react-scroll-area` (already in deps!) or CSS `overflow: auto` with `scrollbar-gutter: stable`.react-custom-scrollbars自 2017 年就停止维护,仓库中 packages/admin-ui/package.json 声明了react-custom-scrollbars: ^4.2.1和@types/react-custom-scrollbars。
值得注意:文档特意强调@radix-ui/react-scroll-area已经在依赖里(admin-ui 的package.json中确认存在@radix-ui/react-scroll-area: ^1.2.18),所以这是"零新增依赖"的迁移。Radix 的ScrollArea提供无障碍(WAI-ARIA)支持、可自定义滚动条样式,是复杂 UI 场景的首选。
对简单场景,文档也给出了零依赖方案:直接用 CSSoverflow: auto配合scrollbar-gutter: stable(为滚动条预留空间,避免内容布局抖动)。
3.4 react-butterfiles → react-dropzone(文件拖拽上传)
Status: ok Alternative: `react-dropzone` is more widely maintained.react-butterfiles当前状态为ok(仍可用),但文档指出更广泛维护的替代品是react-dropzone。这意味着迁移优先级低于前几个"replace"项,可以在未来版本中择机替换。
3.5 react-dnd 全家桶 → @dnd-kit/core + @dnd-kit/sortable(拖拽)
Status: replace Use `@dnd-kit/core` + `@dnd-kit/sortable`. More modern, better maintained, hooks-based.react-dnd生态(react-dnd、react-dnd-html5-backend、dnd-core)是经典的拖拽方案,但 API 较重、依赖 HTML5 后端代理,维护节奏缓慢。仓库中 packages/admin-ui/package.json 声明了react-dnd: ^16.0.1,packages/app-headless-cms/package.json 与 packages/app-website-builder/package.json 则声明了react-dnd+react-dnd-html5-backend,主要服务于内容模型字段排序、页面元素拖拽等场景。
@dnd-kit的优势:
- 完全 hooks 化(
useDndContext、useSortable),与 React 18 心智模型一致; - 内置
sortable预设,拖拽排序开箱即用; - 更小的包体积与更活跃的维护。
3.6 @minoru/react-dnd-treeview(树拖拽)→ @dnd-kit 树方案
Status: replace Depends on react-dnd. If migrating to @dnd-kit, replace this too. Consider `@dnd-kit/core` with tree utilities.@minoru/react-dnd-treeview依赖react-dnd,因此必须与 react-dnd 迁移捆绑进行。从源码看,admin-ui 的 Tree 组件是它的主要消费方:packages/admin-ui/src/Tree/Tree.tsx 与 packages/admin-ui/src/Tree/useTree.ts 中直接 import 了@minoru/react-dnd-treeview的类型(如DropOptions、NodeModel),packages/admin-ui/package.json 声明版本为^3.5.4。
迁移到@dnd-kit时,树结构(嵌套拖放)需要借助@dnd-kit/core的DragOverlay与自定义碰撞检测算法来模拟层级折叠、兄弟节点插入等语义,属于迁移清单中工作量最大的一项,建议单独排期并配套编写测试。
3.7 react-lazy-load → 原生 IntersectionObserver(懒加载)
Status: replace Use native `IntersectionObserver` API with a small hook.文档直接给出了一个可复制的 hooks 实现,用于替代react-lazy-load:
function useLazyLoad(ref: RefObject<Element>) { const [visible, setVisible] = useState(false); useEffect(() => { const obs = new IntersectionObserver(([e]) => e.isIntersecting && setVisible(true)); if (ref.current) obs.observe(ref.current); return () => obs.disconnect(); }, []); return visible; }IntersectionObserver已是所有现代浏览器原生支持的 API,该方案的优势是零依赖、无额外包体积,且行为可预期(进入视口时置为可见,disconnect清理监听避免内存泄漏)。使用时将ref绑定到目标 DOM 节点,用返回的visible控制图片/组件的渲染时机。
3.8 react-transition-group → CSS 过渡 / framer-motion(动画)
Status: replace Use CSS transitions/animations directly or `framer-motion` for complex cases.react-transition-group提供CSSTransition、TransitionGroup等声明式过渡 API,但需要手动维护 enter/exit 的 CSS 类名状态机。仓库中 packages/app-admin/package.json 仍声明了react-transition-group: ^4.4.5。
文档建议:简单进出场动画直接用 CSStransition/@keyframes完成;复杂编排(拖拽跟手、布局动画、页面切换)则引入framer-motion,其 hooks 化 API(useAnimation、AnimatePresence)与 JSX 声明式motion.div能显著降低动画复杂度。
3.9 react-virtualized → @tanstack/react-virtual(虚拟列表)
Status: replace Use `@tanstack/react-virtual` (lighter, maintained, hooks-based). `@tanstack/react-table` is already in deps.react-virtualized是虚拟滚动领域的"老牌"库,但体积庞大、维护停滞。仓库中 packages/admin-ui/package.json 声明了react-virtualized: ^9.22.6与@types/react-virtualized: ^9.22.3。
文档的推荐极具说服力:@tanstack/react-table已经在依赖里(admin-ui 声明@tanstack/react-table: ^9.1.2),而同一生态的@tanstack/react-virtual是轻量、hooks 化的虚拟滚动方案,两者配合可统一表格与列表的虚拟化方案。迁移时需注意 API 差异:react-virtualized的List/AutoSizer需替换为useVirtualizerhook +measureElement动态测量。
3.10 @apollo/react-common / @apollo/react-hooks / @apollo/react-components → @apollo/client v3+(GraphQL)
Status: replace Apollo v2 React bindings. Replace with `@apollo/client` v3+ (single package includes all React hooks).这三者是 Apollo Client v2 时代拆分的 React 绑定包。Apollo Client v3 起已将其合并进单一@apollo/client包,内置useQuery、useMutation、useSubscription、Query/Mutation组件等全部 React API。迁移时直接替换 import 来源即可,v3 的client初始化方式(new ApolloClient({ cache: new InMemoryCache(), link }))与缓存策略也更为现代。
3.11 prop-types → 直接移除(类型安全)
Status: replace TypeScript is already used. `prop-types` is runtime overhead with no value when types are checked at compile time. Remove.这是最干脆的一项:项目已全面使用 TypeScript(全仓库.ts/.tsx源码),编译期类型检查已经覆盖prop-types的运行时校验职责。继续保留prop-types只会增加运行时开销(每次渲染都执行校验逻辑)。文档结论是直接删除。
四、保留(ok)的依赖:与架构深度绑定的现代化栈
以下依赖审计状态均为ok,且大多已在仓库各包中核实存在,短期无需动作:
| 依赖 | 仓库证据 | 备注 |
|---|---|---|
@emotion/react/@emotion/styled/@emotion/css | packages/app-admin/package.json(11.14.0/11.14.1/11.13.5) | 主样式方案,见下文 4.1 |
@lexical/react | 根 package.json(^0.49.0) | Lexical 富文本编辑器官方 React 绑定 |
@monaco-editor/react | packages/admin-ui/package.json(^4.7.0) | Monaco 编辑器封装 |
@radix-ui/react-scroll-area | packages/admin-ui/package.json(^1.2.18) | 见 3.3,同时是替代候选 |
@tanstack/react-table | packages/admin-ui/package.json(^9.1.2) | 见 3.9 |
@testing-library/react/@testing-library/user-event | packages/app-admin/package.json(^16.3.2) | 组件测试体系 |
@fortawesome/react-fontawesome | packages/admin-ui/package.json(^3.5.0) | 图标体系 |
Storybook 全家桶(storybook、@storybook/react-webpack5、addon-a11y、addon-docs、addon-webpack5-compiler-babel) | admin-ui 构建脚本(webiny-admin-build-storybook) | 组件开发/文档环境 |
radix-ui | packages/app-website-builder/package.json(^1.6.7) | 聚合入口包 |
sonner | packages/admin-ui/package.json(^2.0.8) | Toast 通知 |
cmdk | packages/admin-ui/package.json(^1.1.1) | 命令面板,与 packages/command-palette 类场景配套 |
mobx-react-lite | packages/app-admin/package.json(^5.0.3) | 状态管理,admin-ui Tree 组件中useTree亦使用autorun |
use-deep-compare-effect | packages/app-headless-cms/package.json(^1.8.1) | 深比较副作用 |
is-hotkey | packages/app-admin/package.json(^0.2.0) | 快捷键匹配,Lexical 编辑器联动 |
timeago-react | 管理端时间显示 | 相对时间格式化 |
markdown-to-jsx | packages/app-admin/package.json(^9.10.2) | Markdown 渲染 |
class-variance-authority | packages/admin-ui/package.json(^0.7.1) | 变体式样式组合,与 Tailwind 搭配 |
tw-animate-css | packages/admin-ui/package.json(^1.4.0) | Tailwind 动画类 |
csstype | 类型层依赖 | CSS 类型定义 |
react-refresh | 构建链 | Fast Refresh 支撑 |
react-resizable-panels | packages/app-admin/package.json(^4.12.3) | 可拖拽分栏面板 |
4.1 样式方案并存:Emotion + Tailwind,以及 Babel → SWC 的构建链变化
文档对@emotion/*保留的同时给出了一条长期优化线索:
Note: Tailwind CSS is also in deps. Long-term, consolidating to one styling approach reduces bundle. `@emotion/babel-plugin` has been removed — the SWC equivalent (`@swc/plugin-emotion` in `build-tools`) is used instead.- 仓库中 Tailwind 已全面引入:admin-ui 声明
tailwindcss: ^4.3.3、tailwind-merge: ^3.6.0、@tailwindcss/postcss,并构建时将tailwindcss、tw-animate-css列入产出清单。这意味着"Emotion 运行时样式 + Tailwind 静态工具类"两套体系并存,长期来看向单一方案收敛可以减小产物体积。 - 关键构建细节:Emotion 的编译期优化插件已从 Babel 生态切换到 SWC 生态——packages/build-tools/package.json 中声明了
@swc/plugin-emotion: ^15.0.0。也就是说,项目中 Emotion 的css/styled编译时转换由 SWC 插件完成,这与仓库整体使用 SWC/oxc 加速构建链(build脚本基于tsx scripts/buildPackages)的方向一致。迁移或升级 Emotion 时,务必确保@swc/plugin-emotion版本与 SWC 编译器版本兼容。
五、需缩减(reduce)的依赖:reset-css 与 Tailwind preflight 的重叠
Status: reduce Tailwind CSS (already in deps) includes a CSS reset via preflight. May be redundant.reset-css(packages/app-admin/package.json 中声明^5.0.2)提供全局 CSS 重置。但 Tailwind CSS 内置的preflight(基于现代-normalize 的基线重置)已经在依赖中生效,二者功能高度重叠。文档建议评估后移除reset-css,仅保留 Tailwind preflight 一份重置逻辑,进一步压缩全局 CSS 体积。移除时需回归测试表单控件、按钮、列表等基础元素的默认样式,确认无样式回退。
六、落地清单:把审计变成可执行的迁移计划
基于文档与仓库实况,整理为分优先级的执行清单:
P0(收益最大、工作量可控)
prop-types直接移除——纯减法,零功能影响。react-helmet→react-helmet-async——drop-in 替换,改动集中在 5 个 app 包的 import。react-custom-scrollbars→@radix-ui/react-scroll-area——依赖已在库内,无需新增包。
P1(需要组件级改造)4.react-color→react-colorful——API 重写(受控颜色值 + onChange),移除@types/react-color。 5.react-lazy-load→ 内置useLazyLoadhook(文中有完整实现)。 6.react-transition-group→ CSS 过渡或framer-motion。 7.react-virtualized→@tanstack/react-virtual(与既有@tanstack/react-table统一生态)。
P2(工作量最大、需单独排期)8.react-dnd/@minoru/react-dnd-treeview→@dnd-kit/core+@dnd-kit/sortable——涉及 admin-ui 的Tree组件(useTree.ts)与 headless CMS 的字段排序,建议配套拖拽相关测试。 9.@apollo/react-*→@apollo/clientv3+——同步升级 Apollo 数据层。
长期观察10.react-butterfiles→react-dropzone(当前ok,择机替换)。 11.reset-css移除(依赖 Tailwind preflight)。 12. React 18.3.1 → React 19(建议在 1–11 完成后启动)。
七、总结
dependencies/react.md本质上是一份"依赖健康度路线图":它以ok / replace / reduce三档状态清晰划定了 React 生态的保留区、替换区与缩减区。替换区的共同特征是失维护(react-helmet、react-color、react-custom-scrollbars、react-dnd)或与现有技术栈重叠(react-virtualized vs @tanstack、react-transition-group vs CSS/framer-motion),而替代方案几乎都优先指向仓库中已存在的依赖(@radix-ui/react-scroll-area、@tanstack/react-table、Tailwind)或原生 API(IntersectionObserver、CSS transitions),这保证了迁移过程"少引入、多复用"。结合各包package.json与Tree等组件的源码实据,这份清单完全可以作为后续每一次依赖升级 PR 的评审基准与验收标准。
- CMS
- 后端
- 前端
【免费下载链接】webiny-js
Open-source, self-hosted CMS platform on AWS serverless (Lambda, DynamoDB, S3). TypeScript framework with multi-tenancy, lifecycle hooks, GraphQL API, and AI-assisted development via MCP server. Built for developers at large organizations.
相关推荐
open-source-course代码审查指南:提升开源代码质量的7个技巧
open source course代码审查指南:提升开源代码质量的7个技巧 开源项目协作中,代码审查是确保代码质量和项目可持续发展的关键环节。无论您是开源新手
CMS后端前端Dependencies:现代化的Windows依赖性查看器
Dependencies:现代化的Windows依赖性查看器 Dependencies 是一个开源的现代版 Dependency Walker ,专为Windo
开发工具桌面应用逆向工程解决Windows DLL依赖问题的现代工具:Dependencies完全指南
解决Windows DLL依赖问题的现代工具:Dependencies完全指南 在Windows开发的日常工作中,我们经常会遇到"找不到指定模块"或"DLL加载
开发工具桌面应用逆向工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考