最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 解剖postcss —— 向前端架构师迈出一小步

    正文概述 掘金(魔术师卡颂)   2021-03-16   857

    最近很火的TailwindCSS有一个功能:

    可以将项目未使用的css选择器从编译后css文件中移除。

    解剖postcss —— 向前端架构师迈出一小步

    这个功能是PurgeCSS实现的。

    链接TailwindCSSPurgeCSS的,则是一个postCSS插件@fullhuman/postcss-purgecss

    不仅TailwindCSS,还有很多知名项目中使用了postCSS插件。比如:

    很多人在项目中使用autoprefixer插件,为css选择器增加不同的浏览器前缀

    在其内部会根据browserslist指定浏览器版本。

    再去caniuse查找该浏览器版本兼容性支持情况。

    最后通过postCSS的能力改写不支持的css属性。

    可以看到,postCSS正越来越成为前端项目必不可少的依赖。

    同时也有很多关于postCSS的误区,比如认为他是和LessSass一样的css预处理器

    本文会自底向上介绍postCSS,希望通过此文让你对这款大杀器有更深的认识。

    什么是postCSS

    postCSS是一款css编译器。

    类比Babel家族的@babel/parser可以将js代码解析为AST(抽象语法树),再利用众多插件(@babel/plugin-xx)的能力改写AST,最终输出改写后的js代码。

    postCSS利用自身的parser可以将css代码解析为AST,再利用众多插件(上文介绍的autoprefixer就是一种)改写AST,最终输出改写后的css代码。

    解剖postcss —— 向前端架构师迈出一小步

    从这点就能看出其与Less这样的css预处理器的不同 —— postCSS的输入与输出产物都是css文件。

    因此,postCSS也被成为后处理器,因为其通常在css处理链条的最后端。

    解剖postcss —— 向前端架构师迈出一小步

    postCSS的AST

    你可以在astexplorer中选择:

    • 语言:css

    • parser:postCSS

    来了解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 —— 向前端架构师迈出一小步

    节点有如下几种类型:

    • Root:根节点,代表一个css文件

    • AtRule:以@开头的申明,比如@charset "UTF-8"@media (screen) {}

    • Rule:内部包含定义的选择器,比如input, button {}

    • Declaration:key-value键值对,比如color: black;

    • Comment:单独的注释。selectorsat-rule的参数以及value的注释在节点的node属性内

    实现一个简单的插件

    接下来我们从一个插件的实现来了解开发者如何介入postCSS编译流程。

    postcss-focus会为所有:hover选择器增加:focus以提高键盘操作的可用性。

    对于如下代码:

    .a:hover, .b:hover, .c:hover {
      opacity: .5;
    }
    

    经过该插件处理后会输出:

    .a:hover, .b:hover, .c:hover, .a:focus, .b:focus, .c:focus {
      opacity: .5;
    }
    

    你可以安装postcsspostcss-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源码的实现逻辑:

    1. postCSS将输入的css解析为AST

    2. 遍历AST中所有Rule类型节点

    3. 维护一个数组,遍历这个节点的所有selector,每遍历到一个包含:hoverselector就往数组中push一个:focusselector

    4. 将2中得到的数组concat到该节点已有的selectors

    5. 根据改变后的AST输出新的css

    核心源码如下:

    {
      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提供了详细的插件创建文档。甚至提供了create-postcss-plugin用来创建插件的模版代码。

    更多可能性

    由于提供了表达、改写css AST的能力,postCSS的插件可以实现非常多功能。比如:

    postcss-functions

    上文介绍了Declaration节点表达css属性的键值对,其中值为字符串类型。

    那么完全可以自定义值的解析规则。

    body {
      color: getColor();
    }
    

    通过定义getColor函数,并在AST中将其解析为函数执行,就能在css文件中用js写逻辑代码。

    这就是postcss-functions

    stylelint

    配置不同的lint规则,实现css的静态语法检测。这就是stylelint

    总结

    当前postCSS插件按功能划分大体有如下几类:

    • 解决全局css问题,比如提供css module支持

    • 使用未全面兼容的css特性,比如autoprefixer

    • 格式化,提高css可读性

    • 图片和文字处理

    • linters,比如stylelint

    • 不同语法的css支持,比如postcss-html可以解析类html文件中<style>标签内的css语法

    读到这里,相信你会同意:相比LessSasspostCSS才是css处理领域的大杀器。


    起源地下载网 » 解剖postcss —— 向前端架构师迈出一小步

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元