[Bug] [mp-toutiao] 编译时将所有 Component 的子组件强制全量注入 componentPlaceholder="view",导致普通自定义组件被降级渲染为空 <view> 无法显示
- Dominant language
- JavaScript
- Stars
- 41.6k
- Forks
- 3.7k
- Avg merge
- 7h 6m
- Merged PRs (30d)
- 6
Description
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 实例和组件模板根本没有被正确加载挂载,直接降级表现为空 。
4. 对比验证截图说明
未包含该代码时(正常状态):DOM 结构为 ...,组件内部结构渲染完整。
包含该代码时(异常状态): 标签直接被字节渲染层降级为 ,组件自身模板全部消失。
临时修复验证:将 cache.js 中的上述 if (process.env.UNI_PLATFORM === 'mp-toutiao') 代码段注释后,重新编译,抖音端所有组件完全恢复正常显示。
5. 期望与建议
不应在 cache.js 中一刀切地对所有普通 usingComponents 强制无脑注入 componentPlaceholder = 'view';
建议针对真正配置了分包异步化的组件进行精准判断,或者提供显式配置项允许开发者按需开启,避免导致抖音小程序端大面积组件渲染瘫痪。
Contributor guide
Assessment
This issue has not been assessed yet.