Description
Version
2.5.10
Reproduction link
Steps to reproduce
What is expected?
不报错
What is actually happening?
报错
v2.5.10 对组件名称校验引入了breaking change,会导致iView的大部分组件报错。
原因在于这个提交644274c将名称校验提取到了统一的函数validateComponentName
中,这个函数对组件名称校验前都进行了lowercase。
而原来校验过程并不会对组件名称预先lowercase,而是对HTML、SVG、BuiltinTag做区分对待,参见 element.js
iView从设计初就一直坚持使用大写组件名,从实践中发现CamelCase区分度比camel-case更高,有助于保护程序员的视力😂
关于组件名称,我说说我的理解:
组件名称的校验,主要目的在于让template compiler跳过对标准HTML标签的解析,降低解析负担。例如模板中有大量的div、button标签,对每个标签尝试解析是很大的负担。
这就涉及到一个本质问题,到底哪些标签不应该被解析?
从规范视角、解析器视角、用户视角出发,会得到不同的答案,以下从HTML tag和SVG tag来说明:
规范视角
从规范角度来看,HTML5规定HTML Tag是case-insensitive的,意思是button
和Button
是规范有效的标准Tag;SVG规范规定SVG Tag是case-sensitive的,因为SVG遵从XML规范,所以circle
是有效的Tag,而Circle
不是。
所以从规范视角来看,对HTML标签的判断应该不区分大小写,对SVG的标签的判断应该区分大小写。而element.js的实现中恰好相反,对HTML标签的判断应该区分大小写,对SVG的标签不区分大小写。
解析器视角
对于template compiler来说,它实际上可以区分大小写的。之所以In DOM template中不能区分大小写,是因为浏览器在将HTML片段传给tempalte compiler解析的时候,把tag都抹成为lowercase了,导致大小写信息丢失了。所以你在代码中写的大写标签,经过浏览器处理后,template compiler就看不见了。
之所以对HTML标签进行lowercase处理,是为了匹配方便,总不能对button匹配一次,Button再匹配一次吧。而SVG标签是区分大小写的,所以浏览器对SVG内的标签不做lowercase处理,而是传递给SVG engine处理。对于SVG engine来说,理论上应该拒绝Circle的解析,但实现上为了照顾某些粗心的程序员,估计会做容错处理(猜想,未做证实)。
所以从解析器视角来看,HTML和SVG标签应该都不区分大小写。
用户视角
从用户视角来讲,当他声明一个Button
,他的本意到底是说这是一个自定义组件,还是说他手抖了写错了,本意是表示button
?
当用户在template String中明确写了一个大写标签,我认为有很大的可能性他想表达这个组件是自定义组件。毕竟,现有的各种处理HTML的工具软件输出的HTML是大写标签的,也没见过哪个开发者有用大写表示HTML tag的癖好。
对SVG标签来讲,我还没调查是不是有处理SVG的工具软件输出大写标签,例如有的输出<svg>
,有的输出<SVG>
。我觉得这块应该遵守规范,输出标签应该按照SVG规范来,即所谓的“宽进严出”。
所以从用户视角来说,HTML和SVG都应该区分大小写。
总结
前面我说了从规范视角、解析器视角和用户视角,会得出不同的结果。那到底按照哪种方式跟好呢?我认为从用户视角是更好的。从用户视角意味着,template compiler能够最大化的反映开发者的本意,减少开发者理解的负担。虽然,template尽量遵守HTML规范,但它本质不是HTML,所以当HTML规范不符合应用场景时,我们应该打破它。