被尤雨溪diss的Native CSS Modules是什么
前天早上正吃着早饭,唱着歌,开开心心摸鱼时,看到一条尤大的推文:
尤:老实说,我认为
Native CSS Modules
标准是仓促的,再次显示了参与该标准制定过程的人的傲慢
经常看尤大和其他大佬们交流技术,「仓促」、「傲慢」这样的字眼是很少看到的。
今天我们来看看是什么样的标准,让尤大都忍不住diss
。
此CSS Modules非彼Modules
想必做前端的同学对CSS Modules
不会陌生,这里简单介绍下。
CSS Modules
是一套开源的规范,用以解决CSS
的以下问题:
命名冲突
没有模块化
依赖关系不明(样式覆盖问题)
该规范需要打包工具实现。
我们用一个例子来简要了解他的实现细节:
将CSS
文件style.css
引入为style
对象后,通过style.title
的方式使用title class
:
import style from './style.css';
export default () => {
return (
<p className={style.title}>
I am KaSong.
</p>
);
};
对应style.css
:
.title {
color: red;
}
打包工具会将style.title
编译为「带哈希的字符串」:
<h1 class="_3zyde4l1yATCOkgn-DBWEL">
Hello World
</h1>
同时style.css
也会编译:
._3zyde4l1yATCOkgn-DBWEL {
color: red;
}
这样,就产生了独一无二的class
,解决了CSS
模块化的问题。
而今天的主角,并非这位CSS Modules
。
Native CSS Modules
今年6月,谷歌工程师「Justin Fagnani」在推上公布了CSS Modules
的最新进展:
此CSS Modules
并非上文提到的开源方案,而是ES Modules
标准下的一个标准。
该标准实际名称为CSS Module Scripts
,但社区习惯称其为CSS Modules
。
为了与开源方案区别,下文称其为Native CSS Modules
。
该标准用来在JS
中导入CSS
,语法类似ES Modules
:
// ES Modules
import React from "https://cdn.skypack.dev/react@17.0.1";
// Native CSS Modules
import styleSheet from "./styles.css" assert { type: "css" };
导入的CSS
可以应用于document
对象或shadow DOM
。
导入的styleSheet
数据结构如下:
配合Constructable Stylesheets[1]特性,可以解决CSS
:
在多个
shadow DOM
之间复用FOUC
问题(Flash of Unstyled Content
,即由于样式未加载完导致DOM
样式从无到有的闪烁情况)
看起来很nice
,那么尤大diss
的点在哪里呢?
这么多问题?
首选,通过对比可以发现:
该标准命名与现有开源方案冲突
标准的语法与现有开源方案语法相同
第一点,假设在未来一个初学者搜索CSS Modules
,那么结果可能会让他困惑,我搜到的是谁?
第二点,当前各大打包工具都有对开源CSS Modules
方案的支持。
如果未来需要实现Native CSS Modules
的polyfill
,轻则造成重复工作、重则遇到两种方案更迭造成的混乱(想想社区从CJS
过渡到ES Modules
遇到多少问题)。
除此之外,该方案可能对SSR
不友好。
并且,由于Native CSS Modules
需要在所属JS
模块加载后再异步加载,可能会产生很多碎片化的CSS
文件请求。
在有如此多潜在问题的情况下,「Justin Fagnani」仍积极推进该标准的落地,可能这就是尤大认为对方「傲慢」的原因吧。
你可以在讨论1[2]与讨论2[3]看到双方完整的讨论
总结
新的标准,既要在原有基础上有所突破,又受限于现状不能大刀阔斧改变。
这种突破与权衡的博弈每时每刻都是开源的世界上演。
在开发中你有遇到什么特别喜欢或特别想吐槽的特性吗?欢迎评论区讨论~
参考资料
Constructable Stylesheets: https://developers.google.com/web/updates/2019/02/constructable-stylesheets
[2]讨论1: https://twitter.com/justinfagnani/status/1403495082506866690
[3]讨论2: https://twitter.com/Joelbdenning/status/1427427564532887565