Skip to content

[Bug] [mp-toutiao] 编译时将所有 Component 的子组件强制全量注入 componentPlaceholder="view",导致普通自定义组件被降级渲染为空 <view> 无法显示 #6057

Description

@RichOvernigh
  1. 问题描述
    在升级 @dcloudio/* 至较新版本(如 2.0.2-5020420260813001,对应 HBuilderX 5.x)后,编译为抖音小程序(mp-toutiao)平台时,页面或自定义组件内部引用的所有普通子组件(包括第三方 UI 库如 uView 的 u-icon、u-popup、u-modal,以及项目内的本地同步组件)在抖音开发者工具中全部无法显示。

通过抖音开发者工具审查 WXML 元素发现:

原本应该正常渲染的自定义组件标签(例如 ),直接被抖音小程序渲染层退化渲染成了原生的 标签;
该组件自身的模板结构(如弹窗骨架、背景蒙层等)全部丢失未挂载,仅外部传入的 slot 内容被直接挂到了该 内部。
2. 复现环境
uni-app 依赖版本:@dcloudio/*: 2.0.2-5020420260813001(或 HBuilderX 5.2.4+)
运行平台:抖音小程序(mp-toutiao)
项目类型:Vue 2 + CLI 构建模式
3. 根因定位与源码证据
经过对编译器产物与源码的排查,该问题由 @dcloudio/uni-cli-shared 中的强制全量注入逻辑引发。

源码位置:node_modules/@dcloudio/uni-cli-shared/lib/cache.js 第 204-214 行:
javascript
// 嵌套组件获取 props 为 null,使用占组件修正父子组件生命周期执行顺序 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/custom-component/placeholder
if (process.env.UNI_PLATFORM === 'mp-toutiao') {
if (type === 'Component') {
const usingComponentnames = Object.keys(jsonObj.usingComponents)
if (usingComponentnames.length) {
jsonObj.componentPlaceholder = {}
usingComponentnames.forEach(componentName => {
jsonObj.componentPlaceholder[componentName] = 'view' // <--- 问题所在
})
}
}
}
编译产物现象: 导致所有生成的 Component 的 JSON 文件中,只要引用的子组件全部被自动加上了:

json
"componentPlaceholder": {
"u-icon": "view",
"dialog": "view",
"child-component": "view"
}
字节小程序底层机制与冲突点: 字节跳动小程序的官方规范中,componentPlaceholder 是专用于分包异步化/异步组件加载时的占位降级标签。 DCloud 此处为了修复“嵌套组件 props 偶发为 null”的边界问题,无差别、一刀切地将所有普通同步组件都注入了 componentPlaceholder: 'view'。 在字节小程序较新的基础库下,当一个同步组件被声明了 componentPlaceholder: "view",渲染引擎会判定其使用占位渲染规则,导致该自定义组件的 JS 实例和组件模板根本没有被正确加载挂载,直接降级表现为空 。

  1. 对比验证截图说明
    未包含该代码时(正常状态):DOM 结构为 ...,组件内部结构渲染完整。
    包含该代码时(异常状态): 标签直接被字节渲染层降级为 ,组件自身模板全部消失。
    临时修复验证:将 cache.js 中的上述 if (process.env.UNI_PLATFORM === 'mp-toutiao') 代码段注释后,重新编译,抖音端所有组件完全恢复正常显示。
  2. 期望与建议
    不应在 cache.js 中一刀切地对所有普通 usingComponents 强制无脑注入 componentPlaceholder = 'view';
    建议针对真正配置了分包异步化的组件进行精准判断,或者提供显式配置项允许开发者按需开启,避免导致抖音小程序端大面积组件渲染瘫痪。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions