还不会 PostCSS?你 OUT 啦!
是时候每个人都来了解一下 PostCSS 了
—— 它是什么;它实际能做什么
一阵子前,我写过 “见到 PostCSS 很兴奋, 但是我害怕离开 Sass”。从那时起,我已经全心全意拥抱了(并且离开了 Sass,至少是暂时性的)。我已经将 PostCSS 用到了大项目上,向其贡献代码并写作了插件,同项目的维护者交流,以了解更多可能有用的信息;而这全都是顺顺当当的。只是顺顺当当的。
同时, 围绕 PostCSS 的议论和态度各种各样 —— 好奇,兴奋,怀疑,困惑,疲倦,痛苦,防御,刻薄,高兴,轻率冷漠,不屑一顾,摩拳擦掌,等等等等。
针对这种混乱情况我想要指出两点:
-
你不必害怕。外头现有的处理样式代码的工具数量实际上相当少(或者对我而言看起来是如此,因为我也写点 JavaScript)。有更多的可能性并不会对任何人或任何事有所伤害。
-
每一个要编写 CSS 的人都要了解一下 PostCSS 是什么 — 它到底是什么,还有它可以被用来做什么 (不仅仅像一些高调冲动的推文中那样描述的) — 不管结果是不是你会立刻用上它。因为如果你把 PostCSS 想成是 Sass 和 Less 的简单替代的话,那你就弄错了。
针对第一点,我并不知道能做些什么,用安慰的话语、像教练一样的鼓励、轻微的刺激或者什么观点来鼓励你?在这种情况下我可能不是最好的顾问。
因此我会跳到第二点,在这儿我可能会对你有所帮助。因为已经用过 PostCSS 一段时间,我想我已经对它有所了解,并值得同你们分享一下。
当我们说“PostCSS”时指的是什么
用到“PostCSS”这个词汇我们也许指的是以下两种说法的一种:
1. 存在 PostCSS 的情况下,那么就是指工具本身——当你运行指令 npm install postcss
时你将获得的——和
2. 工具强化后的 PostCSS 插件系统。
这个工具本身是一个能够将 CSS 解析成抽象语法树(abstract syntax tree(AST))的 Node.js 模型;通过“插件”方程的任何元素来传递 AST;然后将 AST 反向转换为一个串,你可以将其输出为一个文件。对于每一个方程,AST 可能通过转换进行传递,也可能不通过转换就传递;通过追踪任何一个改变来产生资料图。
AST 提供一个直接的应用程序编程接口(API)让开发者能够使用它开发插件。比方,你可以重复循环每一条设定在文件 css.eachRule()
中的任何规则,或者文件 rule.eachDecl()
中的任何声明。你可以从rule.selector
中获得规则选择器,或者从 atRule.name
中获得每一个“@规则(atRule.name
)”的名字。从这几个例子你就可以看出 PostCSS 的 API 能让使用 CSS 源代码的工作变得相当容易(这比你依赖于正则表达式,如 chump,要容易的多准确的多)。
这就是目前 PostCSS 所做的一切:它不会更改你的 CSS。然而插件可能会更改你的 CSS,也可能不会。使用解析过的 CSS 时 PostCSS 可以为你做很多你想要做的事。一个插件可能使变量有效,或者使一些其它的有用的语言扩展有效。另一个插件可能改变你的所有的‘a’变成 'k'。另一个插件可能记录一个警告只要你使用了ID选择器。另一个插件可能会添加神秘的 ASCII 码图案到你的样式表的顶部。另一个插件可能会记录你使用过浮点类型声明的次数。诸如此类,永远如此。
PostCSS 可以强化几乎无限的各种各样的插件来读取或操作你的 CSS。这些插件除了能解决问题之外并没有一个统一的调度。
需要注意的是不管是工具本身还是插件系统,它们都直接与 Sass 和 Less 相类似。然而:捆绑一系列相关的插件使得它能够将作者友好型的样式表改换成读者友好型的 CSS,然后你便有了一个与良好的“处理器”相类似的东西。
但是一定要记住的是这些“插件包”和其它非打包形式的插件一样,是系统环境的外加成员。任何给定的插件或插件包都不能够代表"PostCSS":相反,我们有一个正在发展壮大的包含很多个性化模型(经过 PostCSS 强化后的)的系统环境。
PostCSS 模块化几个含义
☞试图保持 PostCSS 是(或应该是)一个与“前处理器”Sass 和 Less 相对的“后处理器”的想法定是被误导了的。
不管你是怎样定义“后处理器”和“前处理器”的,一定会有 PostCSS 插件既是”前处理器“也是”后处理器“。依据大多数的定义,Autoprefixer 是一个标志性的"后处理器“;但是也存在着像 postcss-each,这类正是由”前处理器“组成的插件。
也有一些插件压根就不会转换你的 CSS,比方像 styleint、postcss-bem-linter 和 list-selectors。
如果你想在自己的构建过程中保持纯粹的区别,只有使用 PostCSS 插件才能实现你所想的 “后处理器” — 好吧,真的很好:小心选择你的插件。
构建在 …
☞ 试图把 “PostCSS” 绑定到特定的语法扩展或者转换是一种误解
PostCSS 是底层模块,有助于其他工具的创建;没有那些高层工具(插件)的限制。
所以 PostCSS 并不再是 “关于” 允许你编写未来的 CSS(语法和功能规范草案),而是 “关于” 提供循环,条件和其他类似 Sass 的特性。有一些独立的插件可以同时实现这两者,或者是一些插件包也可以实现这两个功能 (cssnext 和 precss);但是这些都不足以代表 PostCSS。
所有的这些意味着...
☞ 当人们认为他们是在批评“PostCSS”时,他们可能是在批评一些特定的插件,或插件包,或是特定方式使用的特定插件。
批评很好,但是不要欺骗自己不去理会其他基于 PostCSS 的工具,那样会让你以错误的方式错过那些工具。
这就引出了下一个点 …
☞ 你可以在任何时候选择或者不选择任何的 PostCSS 插件。
因为你把它放在那里,每个插件仅仅是你创建过程的一部分。如果一个插件使你不满意,那就移除它。没有人会阻止你去移除它。
记住,那些插件可以通过很多种方式被使用,可能你会因为使用这些不同的插件而感到不悦。
可能你就像 Chris Eppstein 那样不喜欢(postcss 定义的属性)postcss-define-property,你可以创建新的,看起来真正喜欢的,标准的属性。同样地,这也意味着:创建那些看起来不好的,不标准的属性也很容易。
如果你希望一个插件需要更好的例子或者新的选择,你可以贡献你的一份力量,因为……
☞ 插件是相对较小的模块,因此人们乐于响应反馈并做出贡献。
如果你没有查到你想要的插件,你可以通过这个方式去做你想要的……
☞你总是可以构建自己的插件来满足自己的需求.
这是最重要的一点,重要的事情要说两遍 ...
☞你总是可以构建自己的插件来满足自己的需求.
这使得 PostCSS 变得新奇和奇妙 — 它的易用性使你可以尝试一些完全不同的东西。
或者你可以稍微调整里面的东西。如果一些插件使用了你非常喜欢的语法但是功能你很讨厌,可以用它好的语法去写一个衍生插件。如果一些插件提供了你很喜欢的功能但是采用了你痛恨的语法,可以用它好的功能去写一个衍生插件。当其他人抱怨你写的插件时,你能做的是建议他们用自己的喜欢的方式去写自己的插件。
(为了避免听起来扯淡又浮夸)我得说,对于许多设计师和前端开发工程师来说,学习 PostCSS 应该是对 CSS 处理有许多启发的。其实所有 Sass 和 Less 提供的函数,其实并不那么有魔力,或者说非得那么做:那只不过是一帮躲在幕后的人,觉着自己又聪明又能干。你没必要觉着他们比你就强那么多。
通过 PostCSS 来解决问题
在使用 PostCSS 的时候,也提醒了我 CSS 是用来解决问题的。所有的问题都有许多种解决问题的方式。也许我们在选择解决方式的同时,也被诸多的解决方案所限制,甚至在解决问题的同时又制造了新的问题。
自从得到了 PostCSS 的帮助, 我就以问题出发来处理 CSS 方面的工作需求 —— 跟我如何处理 JavaScript 相似。并不同于在我真正了解发生了什么之前就急着去找大量的库,首先我会想想实际要解决的问题是什么;然后我会考虑考虑现有的方案;然后我会使用现有方案,或者开始尝试我自己的方案。
我觉得这个过程是愉快而有乐趣的。
而且,我想它也帮助我简化了处理 CSS 的方式。记住——尽管看起来很久之前——许多的开发者拒绝采用 Sass 和 Less,因为他们担心这些”预处理器“并不足以解决实际的问题,来适应他们可能会向其作品中加入的复杂性。我从来没有真正认同过这种见解(可能因为我从来没有在意过我的构建过程中那一点点复杂度);但我确实得承认那些批评和建议中所认为的,如果你并不认为工具能解决问题,那你就必须强迫自己使用那个工具。
我构建过(并且仍在维护着)一个 重要的 Sass 工具库,因为在我以前的工作中,它为我解决了那些重要的问题,在那些问题中我必须快速地写出一大堆 CSS。现在我有了一个新的工作,面对同以往不同的一些问题 (例如 可扩展性, 以及一些古怪的,单一化主题的需求); 而且为了满足当前的需要,我发现自己更偏好用简约的方式处理 CSS,涉及到的分析工作至少同处理工作一样的多。我也想要限制团队的处置权利,只包含非标准功能特性的选择。PostCSS,它的工具和生态系统,对我当前的需求而言是一个很好的满足。
这就够了
我本准备着写另外一节叫做“现在,先别忙着欢呼高兴,让我们先解决一些针对 PostCSS 居心不良的吐槽。” 但我想到这篇文章已经足够长了。而且我也想过精明的读者自会明白我想要针对这些吐槽进行的辩驳是什么。如果你真的想了解这些东西,可以在 @davidtheclark 发推特给我,我会回复你的。