Skip to content

Avoid rc package deep imports#656

Open
QDyanbing wants to merge 1 commit into
react-component:masterfrom
QDyanbing:avoid-deep-imports
Open

Avoid rc package deep imports#656
QDyanbing wants to merge 1 commit into
react-component:masterfrom
QDyanbing:avoid-deep-imports

Conversation

@QDyanbing
Copy link
Copy Markdown

@QDyanbing QDyanbing commented May 25, 2026

背景

antd 侧需要移除对 rc 包 lib / es 内部路径的依赖,统一改为通过 rc 包根入口使用公开 API。

关联:ant-design/ant-design#58115

调整

  • 升级 @rc-component/select~1.7.1@rc-component/tree~1.3.2
  • @rc-component/select@rc-component/tree 的内部路径导入改为包根入口导入
  • 对不再公开的内部类型改为基于公开类型在包内推导
  • 迁移测试中仍依赖 Enzyme 的用例,避免继续依赖 React 16 adapter
  • 适配 @rc-component/select 新版本展示节点结构,更新相关测试断言和 snapshot

验证

  • npm run compile
  • npm run lint(仅保留现有 react-hooks warning)
  • npm test -- --runInBand

Summary by CodeRabbit

发行说明

  • 兼容性

    • 完整支持 React 18(升级自 16)
    • 更新核心依赖库版本
  • 改进

    • 现代化测试基础设施,提升代码质量与稳定性

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

@QDyanbing is attempting to deploy a commit to the React Component Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Walkthrough

此拉取请求执行了一次全面的测试框架迁移和类型系统重构:从 Enzyme 迁移至 React Testing Library,升级 React 16 到 18,并将关键类型定义从外部包嵌套路径本地化为 src/interface.ts 和相关模块,统一所有依赖导入为包公开入口。

Changes

Enzyme 迁移与类型系统重构

Layer / File(s) Summary
构建配置与依赖更新
jest.config.js, package.json
Jest 配置移除 snapshotSerializers,package.json 升级 React 16→18、@testing-library/react ^12→^16,移除 enzyme/enzyme-adapter-react-16/enzyme-to-json/cheerio,更新 @rc-component 各包版本。
类型系统本地化与导出
src/interface.ts, src/hooks/useDataEntities.ts, src/LegacyContext.tsx
定义并导出 Key/SafeKey/ExpandAction/IconType 在本地 interface.ts;useDataEntities.ts 导出推导的 DataEntity 类型;LegacyContext.tsx 的 keyEntities 字段类型从 DataEntity<any> 收窄为 DataEntity
源代码导入路径调整
src/TreeSelect.tsx, src/OptionList.tsx, src/TreeSelectContext.ts, src/hooks/useCheckedKeys.ts, src/utils/*
TreeSelect/OptionList/LegacyContext 等改从本地 ./interface 或包根导入类型;conductCheck/useControlledState/useId 改从包入口导入;EventDataNode 等从 @rc-component/tree 直接导入;警告与工具函数改为具名导入。
测试基础设施现代化
tests/setup.js, tests/util.tsx, tests/shared/focusTest.js
移除 Enzyme 适配器与原型方法扩展,新增 MessageChannel 模拟与 requestAnimationFrame polyfill;tests/util.tsx 引入 flushTimers()、KeyCode 映射、完整键盘事件字段,新增 clearAll/getSelections/getSelectionText/getInput/getVisibleTreeNodes 辅助函数;focusTest.js 改用 RTL render。
核心测试套件迁移
tests/Select.spec.tsx, tests/Select.props.spec.js
从 Enzyme mount/wrapper 迁移至 RTL render;快照改用 container.firstChild;DOM 选择器从 .rc-tree-select-content-value 改为 .rc-tree-select-content;键盘事件、虚拟列表可见节点、活跃节点移动等场景均更新为 RTL 驱动与断言。
功能测试套件迁移
tests/Select.SearchInput.spec.js, tests/Select.checkable.spec.tsx, tests/Select.fieldNames.spec.tsx, tests/Select.maxCount.spec.tsx, tests/Select.multiple.spec.js, tests/Select.tree.spec.js, tests/Select.tree.treeExpandAction.spec.js, tests/Select.warning.spec.js
搜索、复选、多选、树展开、告警等特定功能从 Enzyme 逐个迁移至 RTL;使用 util 辅助函数(selectNode/triggerOpen/clearSelection 等)替代 wrapper 方法;DOM 查询与 fireEvent 驱动交互,fastSnapshot 改用 container 输出。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • react-component/tree-select#650: 与本 PR 同步在 tests/setup.js 中新增 MessageChannel 模拟实现和 tests/util.tsx 的 RTL 辅助函数,并更新共享测试基础设施。
  • react-component/tree-select#651: 本 PR 在 src/TreeSelect.tsx 中更新的 SemanticName 类型定义(改为从 BaseSelectPropsWithoutPrivate['classNames'] 计算)与该 PR 的语义样式/classNames 类型调整直接相关。
  • react-component/tree-select#633: 两个 PR 均调整代码来适应新的包路径:将 @rc-component/tree 等的嵌套导入(如 /lib/interface)改为公开入口。

Suggested reviewers

  • zombieJ

Poem

酶的年代已远去,
测试库接过接力棒。
十八岁的 React 欢快奔跑,
类型本地化,路径统一明。
兔子迎接新时代的测试春风! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确概括了主要变更内容:避免深度导入rc包内部路径,改用公开入口导入。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

jest.config.js

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

src/LegacyContext.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

src/OptionList.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 20 others

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.

@socket-security
Copy link
Copy Markdown

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

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​types/​react-dom@​19.2.3 ⏵ 18.3.7100 +110076 +185100
Added@​testing-library/​react@​16.3.29910010087100

View full report

Copy link
Copy Markdown

@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 primarily focuses on migrating the project's testing framework from Enzyme to React Testing Library and upgrading core dependencies, including React and React DOM to version 18. The changes involve removing Enzyme-related configurations and dependencies, refactoring extensive test suites to use the new testing library, and introducing a set of helper utilities to facilitate DOM-based testing. Additionally, the PR includes significant refactoring of internal imports and type definitions to improve code consistency. Feedback on the changes highlighted a type mismatch in src/OptionList.tsx, where the scrollTo property was defined as non-nullable despite being potentially undefined in the implementation; a suggestion was provided to align the type definition with the actual component behavior.

Comment thread src/OptionList.tsx
Comment on lines +30 to 38
interface RefOptionListProps {
onKeyDown: React.KeyboardEventHandler;
onKeyUp: React.KeyboardEventHandler;
scrollTo?: (args: unknown) => void;
}

type ScrollTo = NonNullable<React.ComponentRef<typeof Tree>['scrollTo']>;

type ReviseRefOptionListProps = Omit<RefOptionListProps, 'scrollTo'> & { scrollTo: ScrollTo };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

目前的类型定义中,ReviseRefOptionListProps 通过交叉类型将 scrollTo 设为了必填项,且使用了 NonNullable。但在组件实现中(第 278 行),scrollTo 的值来自于 treeRef.current?.scrollTo,在树未渲染(如数据为空)时可能为 undefined。这会导致类型定义与实际行为不符。建议直接在接口中定义可选的 scrollTo 类型,简化定义并保持与实现一致。

Suggested change
interface RefOptionListProps {
onKeyDown: React.KeyboardEventHandler;
onKeyUp: React.KeyboardEventHandler;
scrollTo?: (args: unknown) => void;
}
type ScrollTo = NonNullable<React.ComponentRef<typeof Tree>['scrollTo']>;
type ReviseRefOptionListProps = Omit<RefOptionListProps, 'scrollTo'> & { scrollTo: ScrollTo };
interface RefOptionListProps {
onKeyDown: React.KeyboardEventHandler;
onKeyUp: React.KeyboardEventHandler;
scrollTo?: React.ComponentRef<typeof Tree>['scrollTo'];
}
type ReviseRefOptionListProps = RefOptionListProps;

Copy link
Copy Markdown

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/util.tsx`:
- Around line 82-85: getVisibleTreeNodes incorrectly treats nodes with
aria-hidden="false" as hidden by using node.hasAttribute('aria-hidden'); update
the visibility check in getVisibleTreeNodes to only exclude nodes where
aria-hidden === "true" (e.g., use node.getAttribute('aria-hidden') !== 'true' or
change the query selector to
'.rc-tree-select-tree-treenode:not([aria-hidden="true"])') so that nodes with
aria-hidden="false" are considered visible.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6198b968-8cd7-432d-be77-9030b6fffa7e

📥 Commits

Reviewing files that changed from the base of the PR and between 34b4676 and cfde665.

⛔ Files ignored due to path filters (2)
  • tests/__snapshots__/Select.checkable.spec.tsx.snap is excluded by !**/*.snap
  • tests/__snapshots__/Select.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (25)
  • jest.config.js
  • package.json
  • src/LegacyContext.tsx
  • src/OptionList.tsx
  • src/TreeSelect.tsx
  • src/TreeSelectContext.ts
  • src/hooks/useCheckedKeys.ts
  • src/hooks/useDataEntities.ts
  • src/interface.ts
  • src/utils/legacyUtil.tsx
  • src/utils/strategyUtil.ts
  • src/utils/warningPropsUtil.ts
  • tests/Select.SearchInput.spec.js
  • tests/Select.checkable.spec.tsx
  • tests/Select.fieldNames.spec.tsx
  • tests/Select.maxCount.spec.tsx
  • tests/Select.multiple.spec.js
  • tests/Select.props.spec.js
  • tests/Select.spec.tsx
  • tests/Select.tree.spec.js
  • tests/Select.tree.treeExpandAction.spec.js
  • tests/Select.warning.spec.js
  • tests/setup.js
  • tests/shared/focusTest.js
  • tests/util.tsx
💤 Files with no reviewable changes (1)
  • tests/setup.js

Comment thread tests/util.tsx
Comment on lines +82 to +85
export function getVisibleTreeNodes(element: HTMLElement = document.body) {
return Array.from(element.querySelectorAll('.rc-tree-select-tree-treenode')).filter(
node => !node.hasAttribute('aria-hidden'),
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

getVisibleTreeNodesaria-hidden="false" 会误判为不可见节点

Line 84 当前使用 hasAttribute('aria-hidden'),会把 aria-hidden="false" 也过滤掉,和其他用例中 :not([aria-hidden="true"]) 的可见性语义不一致,可能导致可见节点计数不稳定。

💡 建议修改
 export function getVisibleTreeNodes(element: HTMLElement = document.body) {
   return Array.from(element.querySelectorAll('.rc-tree-select-tree-treenode')).filter(
-    node => !node.hasAttribute('aria-hidden'),
+    node => node.getAttribute('aria-hidden') !== 'true',
   );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/util.tsx` around lines 82 - 85, getVisibleTreeNodes incorrectly treats
nodes with aria-hidden="false" as hidden by using
node.hasAttribute('aria-hidden'); update the visibility check in
getVisibleTreeNodes to only exclude nodes where aria-hidden === "true" (e.g.,
use node.getAttribute('aria-hidden') !== 'true' or change the query selector to
'.rc-tree-select-tree-treenode:not([aria-hidden="true"])') so that nodes with
aria-hidden="false" are considered visible.

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.

1 participant