最近很火的TailwindCSS有一个功能:
可以将项目未使用的css选择器从编译后css文件中移除。
这个功能是PurgeCSS实现的。
链接TailwindCSS与PurgeCSS的,则是一个postCSS插件@fullhuman/postcss-purgecss。
不仅TailwindCSS,还有很多知名项目中使用了postCSS插件。比如:
很多人在项目中使用autoprefixer插件,为css选择器增加不同的「浏览器前缀」。
在其内部会根据browserslist[1]指定浏览器版本。
再去caniuse[2]查找该浏览器版本兼容性支持情况。
最后通过postCSS的能力改写不支持的css属性。
可以看到,postCSS正越来越成为前端项目必不可少的依赖。
同时也有很多关于postCSS的误区,比如认为他是和Less、Sass一样的「css预处理器」。
本文会自底向上介绍postCSS,希望通过此文让你对这款大杀器有更深的认识。
postCSS是一款css编译器。
类比Babel家族的@babel/parser可以将js代码解析为AST(抽象语法树),再利用众多插件(@babel/plugin-xx)的能力改写AST,最终输出改写后的js代码。
postCSS利用自身的parser可以将css代码解析为AST,再利用众多插件(上文介绍的autoprefixer就是一种)改写AST,最终输出改写后的css代码。
从这点就能看出其与Less这样的「css预处理器」的不同 —— postCSS的输入与输出产物都是css文件。
因此,postCSS也被成为「后处理器」,因为其通常在css处理链条的最后端。
你可以在astexplorer[3]中选择:
来了解postCSS如何解析css。
比如,对于如下css代码:
- /**
- * I am KaSong
- */
- @media screen and (min-width: 900px) {
- article {
- padding: 1rem 3rem;
- }
- }
- ul {
- margin: 3rem;
- }
- ul li {
- padding: 5px;
- }
会被postCSS解析为如下树结构的AST:
节点有如下几种类型:
接下来我们从一个插件的实现来了解开发者如何介入postCSS编译流程。
postcss-focus[4]会为所有:hover选择器增加:focus以提高键盘操作的可用性。
对于如下代码:
- .a:hover, .b:hover, .c:hover {
- opacity: .5;
- }
经过该插件处理后会输出:
- .a:hover, .b:hover, .c:hover, .a:focus, .b:focus, .c:focus {
- opacity: .5;
- }
你可以安装postcss、postcss-focus后通过如下demo在控制台看到结果:
- const postcssFocus = require('postcss-focus');
- const postcss = require('postcss');
- const fs = require('fs');
- // 输入的css文件地址
- const from = 'src/a.css';
- const to = 'output/a.css';
- fs.readFile(from, (err, css) => {
- postcss(postcssFocus).process(css, { from, to }).then(result => {
- console.log(result.css)
- })
- })
接下来我们分析postcss-focus源码[5]的实现逻辑:
核心源码如下:
- {
- postcssPlugin: 'postcss-focus',
- // 步骤1
- Rule: rule => {
- // 步骤2
- if (rule.selector.includes(':hover')) {
- let focuses = []
- for (let selector of rule.selectors) {
- if (selector.includes(':hover')) {
- let replaced = selector.replace(/:hover/g, ':focus')
- if (!hasAlready(rule.parent, replaced)) {
- focuses.push(replaced)
- }
- }
- }
- // 步骤3
- if (focuses.length) {
- rule.selectors = rule.selectors.concat(focuses)
- }
- }
- }
- }
这个插件只是为了演示插件的基本工作方法,实际上该插件实现的比较粗糙。
postCSS提供了详细的插件创建文档[6]。甚至提供了create-postcss-plugin[7]用来创建插件的模版代码。
由于提供了表达、改写css AST的能力,postCSS的插件可以实现非常多功能。比如:
上文介绍了Declaration节点表达「css属性」的键值对,其中值为「字符串」类型。
那么完全可以自定义值的解析规则。
- body {
- color: getColor();
- }
通过定义getColor函数,并在AST中将其解析为函数执行,就能在css文件中用js写逻辑代码。
这就是postcss-functions[8]
配置不同的lint规则,实现css的静态语法检测。这就是stylelint[9]
当前postCSS插件按功能划分大体有如下几类:
读到这里,相信你会同意:相比Less、Sass,postCSS才是css处理领域的大杀器。
[1]browserslist:
https://github.com/browserslist/browserslist[2]caniuse:
https://caniuse.com/#search=[3]astexplorer:
https://astexplorer.net/[4]postcss-focus:
https://www.npmjs.com/package/postcss-focus[5]postcss-focus源码:
https://github.com/postcss/postcss-focus/blob/master/index.js[6]插件创建文档:
https://github.com/postcss/postcss/blob/main/docs/writing-a-plugin.md[7]create-postcss-plugin:
https://github.com/csstools/create-postcss-plugin[8]postcss-functions:
https://www.npmjs.com/package/postcss-functions[9]stylelint:
https://github.com/stylelint/stylelint[10]css module:
https://github.com/madyankin/postcss-modules[11]autoprefixer:
https://github.com/postcss/autoprefixer[12]postcss-html:
https://github.com/gucong3000/postcss-html
文章题目:解剖postCSS-向前端架构师迈出一小步
文章分享:http://www.shufengxianlan.com/qtweb/news19/414919.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联