是时候学习PostCSS了

2019-03-27 15:27:40 浏览数 (1)

不久前,我写了“I’m Excited About PostCSS, But I’m Scared to Leave Sass”。从那时起,我全心全意地拥抱PostCSS(离开Sass,至少暂时性的)。我已经在大型项目中使用PostCSS,贡献和创作插件,与维护人员沟通,了解更多可能。这一切都很顺利,十分顺利。

同时,关于PostCSS的议论不断增多,引起各种各样的反应,好奇,兴奋,怀疑,困惑,厌倦,埋怨,抵触、诋毁、兴奋,草率的冷漠,自以为是的不屑,高度赞同,等等。

针对于那些忧虑,我有两点要讲:

  1. 您不必害怕。实际上,处理样式代码工具的数量是非常小的(在同时写JavaScript的我看来)。增加更多的可能性不会伤害任何人或任何事。
  2. 每个写CSS的人都应该学习PostCSS — 学习它究竟是什么,学习它可以用来做什么?(并不只是那些易怒的、无用的空喊者说的那些)— 不管最后您是否会使用它。因为如果您认为PostCSS只是Sass和Less的替代品,那您可能被骗了。

我不知道我可以做什么来鼓励情况1 … 一些安慰的话,教练式的鼓励,温柔的激励,和远景?在这种情形下,我可能不是最好的顾问。

所以我会跳到情况2,我可以帮忙的地方。用PostCSS工作了一段时间,我认为我学到的一些东西是值得分享的。

当我们说“PostCSS”时,我们指的是什么?

提到“PostCSS”这个词,我们可能指下面两种情况之一:

  1. 当运行 npm install postcss的时候,得到的这个工具本身含有PostCSS
  2. 这个工具提供了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,比如说 stylelintpostcss-bem-linterlist-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 闭包



小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。

0 人点赞