不久前,我写了“I’m Excited About PostCSS, But I’m Scared to Leave Sass”。从那时起,我全心全意地拥抱PostCSS(离开Sass,至少暂时性的)。我已经在大型项目中使用PostCSS,贡献和创作插件,与维护人员沟通,了解更多可能。这一切都很顺利,十分顺利。
同时,关于PostCSS的议论不断增多,引起各种各样的反应,好奇,兴奋,怀疑,困惑,厌倦,埋怨,抵触、诋毁、兴奋,草率的冷漠,自以为是的不屑,高度赞同,等等。
针对于那些忧虑,我有两点要讲:
- 您不必害怕。实际上,处理样式代码工具的数量是非常小的(在同时写JavaScript的我看来)。增加更多的可能性不会伤害任何人或任何事。
- 每个写CSS的人都应该学习PostCSS — 学习它究竟是什么,学习它可以用来做什么?(并不只是那些易怒的、无用的空喊者说的那些)— 不管最后您是否会使用它。因为如果您认为PostCSS只是Sass和Less的替代品,那您可能被骗了。
我不知道我可以做什么来鼓励情况1 … 一些安慰的话,教练式的鼓励,温柔的激励,和远景?在这种情形下,我可能不是最好的顾问。
所以我会跳到情况2,我可以帮忙的地方。用PostCSS工作了一段时间,我认为我学到的一些东西是值得分享的。
当我们说“PostCSS”时,我们指的是什么?
提到“PostCSS”这个词,我们可能指下面两种情况之一:
- 当运行
npm install postcss
的时候,得到的这个工具本身含有PostCSS - 这个工具提供了PostCSS插件生态系统
PostCSS工具本身是一个Node.js模块,它把CSS解析为抽象语法树(AST);将AST通过任意数量的“插件”函数传递;然后将AST转换回字符串,您可以将字符串输出到文件中。传递AST的每个函数都可以改变它;生成的sourcemaps会跟踪所有的变化。
AST提供了一个直接的API,开发人员可以使用它来编写插件。比如,您可以使用 css.eachRule()
来遍历某个文件中所有的CSS规则,或者使用 rule.eachDecl()
来遍历某条规则中所有的声明。您可以使用 rule.selector
来获取某条规则的选择器,或者使用 atRule.name
来获取某条at-rule的标识符。从这几个例子可以看出,PostCSS的API使我们可以很容易地处理CSS的源代码(比使用正则表达式要简单和准确得多)
这就是PostCSS做的所有:它并没有改变您的CSS。一个插件可能做到,或者它不会做到。使用解析后的CSS,PostCSS插件几乎可以做任何他们想要做的事。可以启用变量,或者其他一些有用的语言扩展。还可以将您所有的 a
改成 k
。还可以在您使用ID选择器的时候,打印一个警告。还可以在您的样式表头部加上ASCII-art字。还可以统计您使用 float
声明的次数,等等。
PostCSS可以提供无限多种插件读取和操作您的CSS。这些插件并没有统一的规程,除了解决问题。
注意,不是工具本身,也不是插件生态系统与Sass或者Less相似。而是:把这些能将对开发者友好的样式表转译成对浏览器友好的CSS的插件聚合起来,就和那些好的预处理器有些相似了。
但是,请记住,这些插件包只是生态系统的附加产物,就好像所有的那些非打包插件。没有什么插件或者插件包是由PostCSS提供的,但是,我们有一个持续发展的生态系统,包含了许多个人的模块(由PostCSS提供支持)。
PostCSS模块化的几个启示
☞ 相对于Sass和Less预处理器,试图主张PostCSS是“后处理器”的做法是错误的。
不管您怎样定义“后处理器”和“预处理器”,PostCSS的插件总会两个阵营都有。根据应用最广的定义,Autoprefixer是标准的“后处理器”;但是, postcss-each
却又是很明显的“预处理器”了。
同样存在一些插件,它们不会修改您的CSS,比如说 stylelint
、 postcss-bem-linter
、 list-selectors
。
如果您想在自己的构建过程中保持一些纯粹的区别,那就只使用那些您认为的“后处理器”——那很好,但是请仔细挑选您的插件。
以此为基础…
☞ 试图把“PostCSS”绑定到特定的语法扩展或者语法转译上是错误的。
PostCSS是底层模块,便于创建其他工具模块;也没有限制那些上层工具(插件)可以做什么。
所以,PostCSS不是教导您如何写以后版本的CSS(从议案角度提出语法和功能),而是提供闭环、基础条件和其他类似于Sass的特性。确实有插件(cssnext 和 precss)提供了将来CSS版本具有的一些功能,但是它们不代表PostCSS。
这一切都意味着…
☞ 当人们认为他们是在批判“PostCSS”的时候,他们可能是在批评某些插件或插件包,或特定的方式来使用一个特定的插件。
批判性是好的,但是不要由于某些依赖PostCSS的插件欺骗了您自己,让它们把您带到了错误的道路上。
由此引出下一点…
☞ 您可以在任何时间选择添加或者删除任意PostCSS插件。
每个插件仅仅是构建过程的一部分,因为您把它添加了进去。如果某个插件使您不高兴了,尽管删除它,没人会阻拦您。
但是,请记住,有些插件有不同的使用方式,可能换一种方式,您就会喜欢上那个曾经让您生气的插件。
也许,您喜欢Chris Eppstein,不喜欢用 postcss-define-property
来创建新的看起来十分像标准和原生的属性。这里有一个非常简单的办法:创建不十分像原生和标准的新属性。
如果您认为一个插件需要更好的例子和新的选项,您可以做出贡献,因为…
☞ 插件是相对较小的模块,因此它们应该易于响应反馈和修改。
如果您找不到您想要的插件,您想做什么…
☞ 您总是可以创建自己的插件来满足自己的需求。
这是最重要的一点。值得重复…
☞ 您总是可以创建自己的插件来满足自己的需求。
这使得PostCSS新颖和美妙,我们可以很轻松地尝试一些完全不同的东西。
或者您也可以稍微调整一下。如果一些插件使用您喜欢的语法,但您讨厌的功能,您可以创建一个有着“正确”功能的副品。如果其他插件提供了您喜欢的功能,但您厌恶的语法,您可以创建一个有着“正确”语法的副品。当人们看到您的修改和抱怨您的插件时,您也可以建议他们用他们自己的方式写自己的插件。
(冒着听起来荒谬和浮夸的风险……)对于许多设计师和前端开发人员,我建议,想要真正地学习PostCSS应该弄清楚CSS的处理过程。Sass和Less提供的功能并不是魔法:它们不是那样的:尽管那些幕后英雄可能聪明又勤奋,但针对于您自己的情况,您也不能想当然地认为,他们了解的比您更好。
用PostCSS解决问题
使用PostCSS使我意识到:CSS处理的存在是为了解决某些问题;很多问题都有多种解决办法;我可以在多种方法中挑选出适合自己的,甚至是创建自己的。
由于PostCSS,我近来处理CSS需求一直是问题优先,就好像我处理JavaScript一样。在我真正了解需求之前,首先,我会思考真正需要解决的问题是什么;然后,我会考虑既有的这些解决办法,再然后,我会使用已经存在的解决方法或者创造自己的。而不是一开始就从一大堆库中没有目的的寻找。
我认为这个过程非常有趣。
此外,我认为这有助于简化CSS的处理方法。虽然这可能距今很久了,但请记住,以前很多开发者都在某种程度上抵制Sass和Less,因为他们担心“预处理器”解决实际问题的程度并不能弥补它们给工程带来的复杂性。我从来没有真正同意过(也或许是因为我从来不介意在构建过程中增加一点复杂性);但我确实承认了这一批评,并承认如果您不觉得问题被一个工具解决了,您也没必要非使用这个工具。
我创建了(并且持续维护)一个substantial Sass utility library,因为它在我之前的工作中帮我解决了许多重大的问题,那时候我总是要快速拼出许多CSS规则。现在我有了一份新的工作,碰到了其他不同的问题(比如说可扩展性和奇怪的,独特的主题要求);对于我当前的需求,我发现自己更喜欢简约的CSS方式,应用尽可能多的分析处理。我也想限制我团队的处理权力,只包括非标准的特性。PostCSS这个工具和它的生态系统,非常适合我目前的需要。
这就足够了
本来我还想要写另外一章,叫做“现在,为了好玩,让我们解决一些针对PostCSS的拙劣批评”。但我认为这篇文章已经够长了。我相信,聪明的读者已经明白我大多数的反驳是什么样子。如果您确实有一种批评,并且想听到我的反驳,请推特我@davidtheclark,我会回复您。
如果您想评论的话,给我发推特@davidtheclark 或者邮件。
往期精选文章 |
---|
使用虚拟dom和JavaScript构建完全响应式的UI框架 |
扩展 Vue 组件 |
使用Three.js制作酷炫无比的无穷隧道特效 |
一个治愈JavaScript疲劳的学习计划 |
全栈工程师技能大全 |
WEB前端性能优化常见方法 |
一小时内搭建一个全栈Web应用框架 |
干货:CSS 专业技巧 |
四步实现React页面过渡动画效果 |
让你分分钟理解 JavaScript 闭包 |
小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。