Skip to content

Conversation

yoyo837
Copy link
Member

@yoyo837 yoyo837 commented Sep 28, 2025

Summary by CodeRabbit

  • 杂务(Chores)
    • 更新依赖与构建脚本:替换内部工具包为新包、移除 np 并新增 @rc-component/np、升级构建相关依赖,prepublish 脚本改为 rc-np;移除 Now/Vercel 部署配置。
  • 重构(Refactor)
    • 统一内部工具引用与路径格式(事件、布局钩子、相等判断、ref 等);调整不可变组件相关类型与导出签名以改善类型定义,保持运行行为一致。

Copy link

coderabbitai bot commented Sep 28, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

将对依赖与构建脚本进行替换(rc-util -> @rc-component/utilnp -> rc-np),删除 now.json 并格式化 tsconfig;类型签名调整 src/Immutable.tsx,使 makeImmutable/responseImmutable 返回 React.ComponentType<React.ComponentProps<T>>src/context.tsx 仅更改导入路径。

Changes

Cohort / File(s) Summary of edits
依赖与发布脚本(package)
package.json
将依赖 rc-util 替换为 @rc-component/util;prepublishOnly 从 npm run compile && np --yolo --no-publish 改为 npm run compile && rc-np;升级/新增 devDeps(@rc-component/father-plugin@rc-component/np),移除 np
Immutable 组件类型与导入
src/Immutable.tsx
supportRef 导入由 rc-util/lib/ref 改为 @rc-component/util/lib/ref;新增 ImmutableProps<T>,调整内部组件签名与 props/ref 处理,makeImmutableresponseImmutable 返回类型改为 React.ComponentType<React.ComponentProps<T>>,并新增若干类型断言。
导入路径更新(hooks 与比较)
src/context.tsx
useLayoutEffectuseEventisEqual 的导入从 rc-util/... 切换为 @rc-component/util/...,代码逻辑未改动。
部署配置删除
now.json
删除 Vercel/Now 的静态构建配置文件 now.json
格式调整(TypeScript 配置)
tsconfig.json
paths 映射的数组从多行改为单行,仅格式化,语义不变。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

我是小兔子,键盘下跳跃,
依赖换新门,类型悄然缝缀。
import 轻移位,脚本换新桥,
配置删旧页,代码更轻快,
胡萝卜庆功,仓库也会笑。 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title Check ✅ Passed 该标题简明扼要地描述了此次提交的核心变更:将 rc-util 包迁移到 @rc-component/util,符合常见的 “chore” 前缀规范,且不包含多余信息,能够让阅读提交记录的同事快速理解主要意图。
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch move-package

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Summary of Changes

Hello @yoyo837, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request performs a maintenance chore by updating the project's dependency on rc-util to its new scoped package name, @rc-component/util. This change ensures consistency with the new package naming conventions and involves updating the package.json and corresponding import statements in the source files.

Highlights

  • Dependency Migration: The rc-util dependency has been migrated to the new scoped package @rc-component/util.
  • Import Path Updates: All relevant import paths within the source code have been updated to reflect the new @rc-component/util package name.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

socket-security bot commented Sep 28, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​rc-component/​np@​1.0.4701006684100
Updated@​rc-component/​father-plugin@​1.1.0 ⏵ 2.1.382 +310077 +187100
Added@​rc-component/​util@​1.3.010010010090100

View full report

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully migrates the dependency from rc-util to @rc-component/util. The changes are straightforward, updating package.json and the corresponding import paths in the source files. I have one minor suggestion for src/context.tsx to sort the new imports alphabetically, which is a common practice for improving code maintainability. Overall, the changes are correct and well-executed.

@yoyo837 yoyo837 changed the title chore: move rc-util to @rc-components chore: move rc-util to @rc-components/util Sep 28, 2025
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link

codecov bot commented Sep 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (2c5614e) to head (bc162f4).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master       #50   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         4           
  Lines           89        91    +2     
  Branches        24        26    +2     
=========================================
+ Hits            89        91    +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Immutable.tsx (1)

15-15: 上下文类型不匹配,导致 TS 错误与潜在空值误用

默认值是 null,但 createContext<number>(null) 的泛型不允许 null。应显式声明为 number | null,与后续 mark !== null 逻辑一致。

-  const ImmutableContext = React.createContext<number>(null);
+  const ImmutableContext = React.createContext<number | null>(null);
🧹 Nitpick comments (1)
src/Immutable.tsx (1)

4-7: 统一“无 ref 的 props”类型,去掉多处 as any 并匹配 React.memo 比较函数

当前:

  • ImmutableProps<T> 通过 Omit<..., 'ref'> 实现;
  • CompareProps<T> 却基于 React.ComponentProps<T>
  • 导致 shouldTriggerRender(prevProps.current as any, props as any) 以及 <Component {...(props as any)} .../> 等多处 as any

建议统一使用 React.ComponentPropsWithoutRef<T>,同时让 CompareProps<T> 也比较“无 ref 的 props”,从而消除这些 as any 与类型不一致。

- export type CompareProps<T extends React.ComponentType<any>> = (
-   prevProps: Readonly<React.ComponentProps<T>>,
-   nextProps: Readonly<React.ComponentProps<T>>,
- ) => boolean;
+ export type CompareProps<T extends React.ComponentType<any>> = (
+   prevProps: Readonly<React.ComponentPropsWithoutRef<T>>,
+   nextProps: Readonly<React.ComponentPropsWithoutRef<T>>,
+ ) => boolean;
@@
- type ImmutableProps<T extends React.ComponentType<any>> = Omit<React.ComponentProps<T>, 'ref'>;
+ type ImmutableProps<T extends React.ComponentType<any>> = React.ComponentPropsWithoutRef<T>;
@@
-        shouldTriggerRender(prevProps.current as any, props as any)
+        shouldTriggerRender(prevProps.current, props)
@@
-      return <Component {...(props as any)} {...refProps} />;
+      return <Component {...(props as any)} {...refProps} />;
+      // 若上方统一了类型,且 TS 能正确推断,这里的 (props as any) 亦可去除
@@
-      ? (React.memo(React.forwardRef(ImmutableComponent), propsAreEqual) as React.ComponentType<
-          React.ComponentProps<T>
-        >)
-      : (React.memo(ImmutableComponent, propsAreEqual) as unknown as React.ComponentType<
-          React.ComponentProps<T>
-        >);
+      ? React.memo(React.forwardRef(ImmutableComponent), propsAreEqual)
+      : React.memo(ImmutableComponent, propsAreEqual);

说明:如果担心外部已传入基于带 ref 的比较函数,可在文档中明确 CompareProps 的比较目标是“去 ref 的 props”。Based on learnings

Also applies to: 9-10, 54-55, 87-91, 100-105

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71eeb29 and 86ecf9c.

📒 Files selected for processing (3)
  • package.json (1 hunks)
  • src/Immutable.tsx (6 hunks)
  • src/context.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/context.tsx
  • package.json
🔇 Additional comments (1)
src/Immutable.tsx (1)

1-1: 依赖迁移至 @rc-component/util 路径变更正确

supportRef@rc-component/util/lib/ref 引入符合迁移目标与分路径导入最佳实践。

Comment on lines 34 to 38
function makeImmutable<T extends React.ComponentType<any>>(
Component: T,
shouldTriggerRender?: CompareProps<T>,
): T {
): React.ComponentType<React.ComponentProps<T>> {
const refAble = supportRef(Component);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

返回类型从原始组件坍缩为 ComponentType 导致 ref 能力丢失,且禁止直接传入 forwardRef 组件

  • 约束 T extends React.ComponentType<any> 会拒绝 React.ForwardRefExoticComponent 与部分 ExoticComponent,这在库场景里是破坏性的。
  • 将返回值强行断言为 React.ComponentType<...> 会丢失 ref 的类型信息(消费端 <Comp ref=... /> 可能报错/无提示)。

建议:为 makeImmutable 提供函数重载以允许 forwardRef 入参,并在 refAble 分支返回真实的 ForwardRefExoticComponent,避免丢失 ref 类型。

-  function makeImmutable<T extends React.ComponentType<any>>(
-    Component: T,
-    shouldTriggerRender?: CompareProps<T>,
-  ): React.ComponentType<React.ComponentProps<T>> {
+  // Overloads: preserve ref typing for forwardRef, and allow normal ComponentType
+  function makeImmutable<T extends React.ForwardRefExoticComponent<any>>(
+    Component: T,
+    shouldTriggerRender?: CompareProps<T>,
+  ): T;
+  function makeImmutable<T extends React.ComponentType<any>>(
+    Component: T,
+    shouldTriggerRender?: CompareProps<T>,
+  ): React.ComponentType<React.ComponentProps<T>>;
+  function makeImmutable<
+    T extends React.ComponentType<any> | React.ForwardRefExoticComponent<any>
+  >(Component: T, shouldTriggerRender?: CompareProps<any>) {
@@
-    return refAble
-      ? (React.forwardRef(ImmutableComponent) as React.ComponentType<React.ComponentProps<T>>)
-      : (ImmutableComponent as unknown as React.ComponentType<React.ComponentProps<T>>);
+    return refAble ? React.forwardRef(ImmutableComponent) : ImmutableComponent;
   }

Also applies to: 72-75

Comment on lines 81 to 85
function responseImmutable<T extends React.ComponentType<any>>(
Component: T,
propsAreEqual?: CompareProps<T>,
): T {
): React.ComponentType<React.ComponentProps<T>> {
const refAble = supportRef(Component);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

responseImmutable 同样存在 ref 与类型坍缩问题;memo 比较函数的入参与内部 props 类型不一致

  • 目前返回被断言为 React.ComponentType<...>,会丢失 memo/forwardRef 的精确信息。
  • propsAreEqual 的签名使用的是 React.ComponentProps<T>,但这里 memo 的是 ImmutableComponent(其 props 已去掉了 ref),存在类型不一致。

建议:添加重载以保留 memo(forwardRef(...)) 的精准类型,并让比较函数对“无 ref 的 props”进行比较。

-  function responseImmutable<T extends React.ComponentType<any>>(
-    Component: T,
-    propsAreEqual?: CompareProps<T>,
-  ): React.ComponentType<React.ComponentProps<T>> {
+  // Overloads: preserve accurate exotic component types
+  function responseImmutable<T extends React.ForwardRefExoticComponent<any>>(
+    Component: T,
+    propsAreEqual?: CompareProps<T>,
+  ): React.MemoExoticComponent<T>;
+  function responseImmutable<T extends React.ComponentType<any>>(
+    Component: T,
+    propsAreEqual?: CompareProps<T>,
+  ): React.MemoExoticComponent<React.ComponentType<React.ComponentProps<T>>>;
+  function responseImmutable<
+    T extends React.ComponentType<any> | React.ForwardRefExoticComponent<any>
+  >(Component: T, propsAreEqual?: CompareProps<any>) {
@@
-    return refAble
-      ? (React.memo(React.forwardRef(ImmutableComponent), propsAreEqual) as React.ComponentType<
-          React.ComponentProps<T>
-        >)
-      : (React.memo(ImmutableComponent, propsAreEqual) as unknown as React.ComponentType<
-          React.ComponentProps<T>
-        >);
+    return refAble
+      ? React.memo(React.forwardRef(ImmutableComponent), propsAreEqual)
+      : React.memo(ImmutableComponent, propsAreEqual);
   }

Also applies to: 100-105

🤖 Prompt for AI Agents
In src/Immutable.tsx around lines 81-85 (also apply same changes to 100-105):
responseImmutable currently collapses precise memo/forwardRef types and
mis-signatures the comparator by using React.ComponentProps<T> (which still
includes ref) while the internal ImmutableComponent strips ref; fix by adding
overloads for responseImmutable to preserve exact return types when T is a
ForwardRefExoticComponent/Ref/MutableRef—i.e. provide a signature that returns
the same ForwardRefExoticComponent/Named memo-wrapped type when a ref-supporting
component is passed—change propsAreEqual to accept props with ref removed (use
OmitRefProps or JSX.LibraryManagedAttributes/RemoveRef wrapper type) and use
correct generics when calling React.memo and React.forwardRef so TypeScript can
infer the precise combined type rather than collapsing to ComponentType; update
internal typing around supportRef/ref handling to map T -> PropsWithoutRef and
ensure the exported return type matches the specific memo/forwardRef type rather
than generic ComponentType.

@yoyo837 yoyo837 changed the title chore: move rc-util to @rc-components/util chore: move rc-util to @rc-component/util Sep 29, 2025
@zombieJ zombieJ merged commit 4d731ba into master Sep 29, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants