Mitosis 编译 Vue 产物,模板含有 props.style 竟然会出错?

大家好,我是馋嘴的猫。最近在用 Mitosis 配合组件库的开发,但在编译为 Vue 的产物时,遇到了一个奇怪的编译问题。借助这个问题,重新认识了 Mitosis 和 Vue 的关键字限制。

请随我的正文,一起来探讨下吧~

问题

在编译 Mitosis 的模板文件时,如果文件里面含有props.style,则在打包 Vue 平台产物时会失败,并提示Error: avoid using JavaScript keyword as property name: "style"。

但同时,将此份模板文件编译为其他平台,如 React 和 Solid ,则正常无误。

问题复现 Playground

Mitosis Playground

可在 Mitosis Playground 的右边窗口选择 React、Solid、Vue 选项卡查看编译结果,仅在选择 Vue 时会出错,出错信息可在 Chrome 的 console 里查看。

Mitosis 出错源码

typescript 复制代码
export default function MyComponent(props) {
  return (
    <div style={props.style}/>
  );
}

分析

在编译 Vue 的时候出错提示为:

text 复制代码
Error: avoid using JavaScript keyword as property name: "style"

在 Mitosis 源码查找出错提示,发现为 getProps 方法抛出的错误,代码位置

继续追查下去,可以重现 Mitosis 在遇到"props.style"编译出错的全流程

出错流程解析

  1. Vue 的 generator 通过 getProps 方法收集所有的 props 属性,代码链接
typescript 复制代码
const props = Array.from(getProps(component));
  1. 在 getProps 方法里,匹配所有满足props.xxx的赋值,并且对 xxx 的值展开校验。

  2. 如果属性值命中了 prohibitedKeywordRE 的正则表达式(如props.style),则 Mitosis 会丢出错误 Error: avoid using JavaScript keyword as property name: "style" ,即本篇一开始提示遇到的错误。 代码链接

  3. 至此,全流程完结。

Mitosis为何要做这样的限制?

查看源码,发现 Mitosis 官方在一笔提交里加上了对 Vue 的关键字限制,代码链接

这笔提交,主要是两处关键字的限制,与 Vue 是对齐的,可对照 Vue 仓库的源码查看:

  1. utils.ts 里的限制,代码链接
typescript 复制代码
export const isReservedAttribute = makeMap('key,ref,slot,slot-scope,is')
  1. attrs.ts 里的限制,代码链接
typescript 复制代码
export const isReservedAttr = makeMap('style,class')
  1. 结合以上的限制,Vue 在 dev 模式下,会对不符合条件的 props,抛出 warning,代码链接
typescript 复制代码
if (__DEV__) {
  const hyphenatedKey = hyphenate(key);
  if (
    isReservedAttribute(hyphenatedKey) ||
    config.isReservedAttr(hyphenatedKey)
  ) {
    warn(
      `"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,
      vm
    );
  }
}

Vue 为何要做这样的限制

那回过头来,Mitosis 是为了对齐 Vue 而做的关键字限制。那为什么 Vue 一开始就要做限制呢?

原因

Vue 支持透传特性,可以实现组件不声明 class、style 等属性,也能自动接收父组件的对应属性,并添加到根元素上,文档如下所示:

所以,在开发者使用 React jsx ,并使用props.style来实现接受父组件传进来的 style 时,Vue 中却是不需要这么实现的。

并且,Vue 还实现了 class 和 style 的自动合并,所以也可以说,Vue 从另外一方面,更不鼓励从 props 手动取 class 和 style 的值了。

鉴于以上的原因,Vue 对 props 数组加上了关键字限制,如 class、style 等。

关键字限制会影响 Mitosis 什么平台的编译?

  1. 首先,getProps 函数里的校验逻辑,是导致 props 关键字限制的直接原因。

  2. 其次,getProps 函数会被以下平台的 Mitosis generator 调用: Angular,Vue,Html,Lit,Stencil,Svelte,因此,这些平台打包时,都会受到关键字限制的影响。

结论

  1. Mitosis 作者对照 Vue 对 props 的关键字限制,在 Mitosis 的实现里添加了一样的关键字限制,导致了props.style 编译错误的发生。

  2. 因为关键字限制的校验仅在 getProps 方法会被调用,因此会导致如props.style在 Vue 上会编译出错,在 React 上却编译正常(因 React generator 没有调用 getProps 函数)

  3. 这些关键字限制是 Vue 独有的,但 Mitosis 官方却把此限制运用在 Angular,Vue,html,lit,stencil,svelte 这几个平台。可能是为了保证同一份 mitosis 能在所有平台都能编译,所以限制条件是取最苛刻的,没有做很完善的平台区分,但是这对于仅使用Angular、lit等框架的开发者是不太方便的(限制了本来没有必要限制的props)

  4. 在书写 Mitosis JSX 时,因为 Mitosis 的校验逻辑限制,导致即使开发者尝试通过 useStore 来实现 getter method,类似以下代码,也会报错:

typescript 复制代码
// still throws out error about "props.style"
const state = useStore({
  get myStyle() {
    return props.style;
  },
});
  1. 如果开发者只需要生成 React 和 Solid 产物,暂不会遇到此问题。但如果需要 Angular,Vue,Html,Lit,Stencil,Svelte 这几个平台的产物,则需要想办法绕开关键字限制,比如与父组件约定传入其它非限制 key 值的 props。
相关推荐
史迪仔0112几秒前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt
AI_Claude_code1 分钟前
ZLibrary访问困境方案四:利用Cloudflare Workers等边缘计算实现访问
javascript·人工智能·爬虫·python·网络爬虫·边缘计算·爬山算法
AwesomeCPA5 分钟前
Miaoduo MCP 使用指南(VDI内网环境)
前端·ui·ai编程
前端大波6 分钟前
前端面试通关包(2026版,完整版)
前端·面试·职场和发展
qq_4335021830 分钟前
Codex cli 飞书文档创建进阶实用命令 + Skill 创建&使用 小白完整教程
java·前端·飞书
IT_陈寒36 分钟前
为什么我的Vite热更新老是重新加载整个页面?
前端·人工智能·后端
一袋米扛几楼981 小时前
【网络安全】SIEM -Security Information and Event Management 工具是什么?
前端·安全·web安全
小陈工1 小时前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python
Cobyte1 小时前
3.响应式系统基础:从发布订阅模式的角度理解 Vue2 的数据响应式原理
前端·javascript·vue.js