-
Notifications
You must be signed in to change notification settings - Fork 4.9k
feat(inject): 小程序支持插入已有原生组件的副本组件 #18572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough引入对 Changes
Sequence Diagram(s)sequenceDiagram
participant Config as 用户配置
participant Plugin as 插件初始化 (onSetup)
participant Template as 模板构建
participant Utils as 属性过滤
participant Runtime as onSetupClose 合并阶段
Config->>Plugin: 提供组件配置 (可能含 $duplicateFromComponent)
Plugin->>Template: 调用 buildComponentTemplate / createMiniComponents
Template->>Utils: 请求属性过滤
Utils-->>Template: 返回已移除 `$duplicateFromComponent` 的 prop 集合
Template->>Template: 若存在 $duplicateFromComponent,重映射 nodeName 为 dashed 形式
Plugin->>Runtime: 触发 onSetupClose
Runtime->>Runtime: 遍历组件列表
alt 组件含 $duplicateFromComponent 且 internalComponents 存在
Runtime->>Runtime: Object.assign 合并 internalComponents -> 公共组件
end
Runtime->>Template: 调用 template.mergeComponents
Runtime-->>Config: 完成组件合并与模板准备
Estimated code review effort🎯 3 (中等) | ⏱️ ~35 分钟 可能需额外关注:
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
🧰 Additional context used🧠 Learnings (3)📚 Learning: 2025-09-05T18:40:45.775ZApplied to files:
📚 Learning: 2025-05-25T18:02:31.387ZApplied to files:
📚 Learning: 2025-08-08T02:32:58.265ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
🔇 Additional comments (3)
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. Comment |
There was a problem hiding this 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
🧹 Nitpick comments (2)
packages/taro-plugin-inject/src/index.ts (1)
58-64: 建议增加输入验证和错误处理组件合并逻辑实现基本正确,但建议增强健壮性:
- 类型验证:
$duplicateFromComponent应验证为字符串类型- 循环引用检测:如果组件 A 复制 B,B 复制 A,会导致问题
- 错误提示:当
$duplicateFromComponent引用不存在的组件时,应提供明确的错误信息建议应用以下改进:
if (components) { + const processedKeys = new Set<string>() for (const key in components) { const { $duplicateFromComponent } = components[key] || {} const internalComponents = platform?.template?.internalComponents || {} - if (hasOwn(components, key) && $duplicateFromComponent && internalComponents[$duplicateFromComponent]) { + if (hasOwn(components, key) && $duplicateFromComponent) { + // 验证 $duplicateFromComponent 是字符串 + if (typeof $duplicateFromComponent !== 'string') { + console.warn(`[taro warn] 组件 ${key} 的 $duplicateFromComponent 必须是字符串类型`) + continue + } + // 检查循环引用 + if (processedKeys.has($duplicateFromComponent)) { + console.warn(`[taro warn] 检测到组件 ${key} 与 ${$duplicateFromComponent} 之间可能存在循环引用`) + continue + } + // 验证引用的组件存在 + if (!internalComponents[$duplicateFromComponent]) { + console.warn(`[taro warn] 组件 ${key} 引用的 $duplicateFromComponent "${$duplicateFromComponent}" 不存在`) + continue + } + processedKeys.add(key) components[key] = Object.assign({}, internalComponents[$duplicateFromComponent], components[key]) } }packages/taro-plugin-inject/README.md (1)
214-250: 旧版本方案的差异说明不够清晰提供旧版本的替代方案很有帮助,但建议补充说明新旧方案的区别:
4.1.8+ 版本(使用
$duplicateFromComponent):
- 自动继承源组件的所有属性
- 在模板生成阶段就确定了标签映射关系
- 更安全、更易维护
4.1.8 以下版本(使用自定义插件):
- 需要手动配置所有属性(不会自动继承 View 的属性)
- 在构建产物阶段进行字符串替换
- 需要额外的插件代码
建议在 Line 214 之后添加一段说明:
对于 4.1.8 以下的版本,可配合插件来实现类似的效果: > **注意**:此方案与 4.1.8+ 的 `$duplicateFromComponent` 方案有本质区别。旧方案不会自动继承 View 组件的属性,需要在 `components` 配置中手动声明所有需要的属性。建议升级到 4.1.8+ 以使用更完善的实现。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/shared/src/template.ts(3 hunks)packages/shared/src/utils.ts(1 hunks)packages/taro-plugin-inject/README.md(4 hunks)packages/taro-plugin-inject/src/index.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-05-25T18:02:31.387Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17746
File: packages/taro-runtime/tsdown.config.ts:10-16
Timestamp: 2025-05-25T18:02:31.387Z
Learning: 在 taro-runtime 包的 tsdown 配置中,必须禁用 treeshake 来保留 dom-external/index.js 文件。
Applied to files:
packages/taro-plugin-inject/src/index.tspackages/taro-plugin-inject/README.md
📚 Learning: 2025-08-25T22:16:50.118Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json:2356-2356
Timestamp: 2025-08-25T22:16:50.118Z
Learning: The file `packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json` is auto-generated by the post-build script `packages/taro-platform-h5/scripts/post-build.mjs`, which copies content from `taro-platform-h5/dist/definition.json`. This file should not be manually edited.
Applied to files:
packages/taro-plugin-inject/src/index.ts
📚 Learning: 2025-09-05T18:40:45.775Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/taro-platform-harmony-hybrid/package.json:43-45
Timestamp: 2025-09-05T18:40:45.775Z
Learning: 在 tarojs/plugin-platform-harmony-hybrid 包中,tarojs/components-library-react、tarojs/components-library-solid 和 tarojs/components-library-vue3 必须作为直接依赖(dependencies)而不能作为 peer 依赖,因为插件源码中有对这些包的直接引用,包括 componentAdapter* getter 方法和 webpack 别名配置。
Applied to files:
packages/taro-plugin-inject/src/index.tspackages/taro-plugin-inject/README.md
📚 Learning: 2025-08-08T02:32:58.265Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Applied to files:
packages/taro-plugin-inject/README.md
🧬 Code graph analysis (2)
packages/shared/src/template.ts (1)
packages/shared/src/utils.ts (4)
hasOwn(66-69)capitalize(60-62)toCamelCase(42-54)toDashed(38-40)
packages/taro-plugin-inject/src/index.ts (1)
packages/shared/src/utils.ts (1)
hasOwn(66-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Build Rust Binding / stable - aarch64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-gnu
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
- GitHub Check: Build Rust WASM / stable - wasm32-wasi
- GitHub Check: Build Rust Binding / stable - aarch64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
🔇 Additional comments (5)
packages/shared/src/utils.ts (1)
194-194: 正确过滤内部元数据属性将
$duplicateFromComponent添加到过滤列表中是正确的做法,确保这个内部配置不会被暴露为组件的实际属性。这与已有的focus、blur过滤逻辑保持一致。packages/taro-plugin-inject/src/index.ts (1)
4-4: LGTM - 正确引入工具函数引入
hasOwn用于属性存在性检查是合理的,避免了原型链污染问题。packages/shared/src/template.ts (2)
142-156: 正确实现属性跳过机制使用
skipProps数组来排除$duplicateFromComponent是一个良好的设计:
- 代码可扩展性强,便于未来添加更多需要跳过的属性
- 在属性值转换之前就进行过滤,避免了不必要的处理
- 与现有的
bind*和事件处理逻辑保持一致
310-319: nodeName 重映射逻辑已验证为正确经过验证,代码在以下三个方面均工作正常:
大小写转换链:正确将
comp.nodeName(dashed 格式)通过toCamelCase和capitalize转换后查找internalComponents。例如tab-index-view→TabIndexView。模板名称不受影响:模板名称使用
nodeAlias而非nodeName(见第 451 行tmpl_${level}_${nodeAlias}),因此重映射不会改变模板名。属性继承正确:当组件具有
$duplicateFromComponent时,插件层(taro-plugin-inject第 60-62 行)已在运行时合并了内部组件的属性,确保重映射后的标签使用完整属性。该机制是插件系统的设计特性,允许自定义组件委托给原生组件。代码实现无误。
packages/taro-plugin-inject/README.md (1)
126-132: 良好的无障碍适配示例为 View 组件添加 aria 属性的示例很有帮助,展示了
components配置的实际应用场景。
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #18572 +/- ##
========================================
Coverage 55.97% 55.97%
========================================
Files 416 416
Lines 21563 21563
Branches 5301 5302 +1
========================================
Hits 12070 12070
+ Misses 8012 7876 -136
- Partials 1481 1617 +136
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
cebfa01 to
2df2132
Compare
这个 PR 做了什么? (简要描述所做更改)
这个 PR 是什么类型? (至少选择一个)
这个 PR 涉及以下平台:
Summary by CodeRabbit
发布说明
新功能
Bug 修复
文档