Postcss介绍

本文详细讲述了PostCSS如何通过CSS预处理器和后处理器功能解决CSS开发中的问题,如变量、嵌套和跨浏览器兼容,并展示了如何在Webpack项目中集成PostCSS实现优化。
摘要由CSDN通过智能技术生成

前言

说起web前端,大家总不忘想起前端三大组成部分:html,js和Css。但是在多数web开发工程师的眼里,css总是一段苦涩的记忆。

动图封面

就像这张图中一样,在早期进行大型的项目开发中,错综复杂的 Css 会让开发者崩溃的。

产生这些问题的原因来源于 Css 本身,比如 Css 的语法不够强大,没有嵌套层级,需要书写大量的重复性的选择器。再例如没有变量和合理的样式复用的机制,是的逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护。

为了解决这些问题,便诞生了 Css 预处理器。

Css预处理器

什么是css预处理器呢?

预处理器是基于 Css,在其上做了一层属于自己的DSL(Domain specific language),用来解决 Css 遇到的问题。

Css 赋予了 Web 工程师在 Css 方面新的能力,本文以Sass为例。 第一:完全兼容 Css3。在前端快速发展时候,也会有跟不上的,那就是浏览器的更新速度,浏览器的厂商太多,不同的厂商对 Css 标准的解析效果不同,进而对新的特性许多新的特性无法直接在当前浏览器中使用,使得 Css在不同浏览器中兼容就带来了很大的问题。但是在 Sass 中可以放心的使用 Css3 的新特性。

第二,扩展了 Css 的功能:增加了变量,嵌套,混合等功能。长期以来,Css 被人诟病的一个问题就是没有逻辑处理。增加了逻辑处理可以让代码复用性更强。解决了原本 Css 的语法不够强大的问题。 最容易上手的就是嵌套和变量了。

// sass 
$red_color: #ea7142;
$green_color:#299e22;
#hello_sass{
    color: $red_color;
    .font_green_color{
        color: $green_color;
    }
}
===>
#hello_sass{
    color: #ea7142;
}
#hello_sass .font_green_color{
    color: #299e22;
}

Css 预处理器的代码是无法直接运行于浏览器的,所以我们还需要进行编译解析成为 Css 文件。这个过程中,我们就可以添加很多的构建环节,比如代码的检查,压缩,排序等等。

于是诞生了 Css 后处理器,这就是本文的重点 --- Postcss

Postcss介绍

Postcss 是一个使用js插件来转换样式的工具,Postcss 的插件会检查你的css。

其中最常用的插件莫过于 autoprefixer 这个插件了,这个插件会添加 vendor 浏览器的前缀,让我们不需要为了兼容而不断的写-webkit-这样无聊的代码,丢掉了历史包袱。 那你可能会有疑问了,为什么我创建的vue项目也不需要写前缀啊?原来是 vue-cli 在项目创建的时候已经默认配置了 autoprefixer 这个插件了。 在 Postcss 中还有很多amazing的插件,比如可以自动转换 px 来进行不用屏幕不同宽度大小的适配的 postcss-px-to-viewport,还有强迫症的福音,可以自动对Css属性依照设定的规则进行排序的 Postcss-sorting 等等。

当然,纸上得来终觉浅,让我们来试用一下 Postcss。

Postcss实践

构建一个js项目。

mkdir test-poctcss
npm init 
npm install --save-dev css-loader style-loader webpack webpack-cli mini-css-extract-plugin
// 安装poctcss相关依赖 
npm install --save-dev postcss postcss-loader

初始化项目,使用 webpack 来进行项目的打包,创建目录结构

我们使用 postcss.config.js 来对 Postcss 进行配置。现在我们仅仅以 autoprefixer 为例子。

npm install --save-dev autoprefixer

// postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

这样,我们就成功的将插件插入了 Postcss 这个方法中。接下来就是让 webpack 认识 Postcss 了。在安装Postcss 的时候我们还引入了poctcss-loader这个包,我们将打包css相关的内容时候,先调用postcss-loader。

// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  entry: './src/js/index.js',
  output: {
    filename:'bundle.js',
    path:path.resolve(__dirname,'dist')
  },
  module: {
    rules:[
      {
        test: /\.css$/,
        use:
          [{
            loader: MiniCssExtractPlugin.loader
          },
            'css-loader', 'postcss-loader' ]

      },
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'main.css'
    })
  ]
}

// index.js
import '../style/index.css'
const div = document.createElement('div')
div.innerHTML = 'hello postcss'
div.className = 'hello_postcss'
document.body.append(div)

// index.css
.hello_postcss{
    color: #00DD00;
    display: flex;
}

配置好了 webpack , js 和 css 文件.我们使用webpack来打包

webpack --mode development

ok。已经成功打包了。让我们看看 dist 下面的 css 文件长什么样吧。

// main.css
.hello_postcss{
    color: #00DD00;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
}

可以看见 Postcss 将我们css中的display:flex打包转换成了多条不同前缀的属性。

Postcss原理

为什么poctcss能够完成这些功能呢?通过阅读分析源码,得知。 我们在构建项目的时候,通过webpack会把css文件的内容传送给postcss-loader, postcss-loader会解析postcss.config中的插件,传输给 Postcss,Postcss 会解析传入的css,将其转换为一个AST,然后通过各种不同的插件来对这个AST进行操作,最终序列化新的 css,最后将结果返回到 postcss-loader,进行 webpack 下一个 loader 的操作。

既然看了 PostCss 的工作原理,那我们也来看看 autoprefixer 到底是怎么工作的。就拿 display 属性来看。

class DisplayFlex extends Value {
  constructor (name, prefixes) {
    super(name, prefixes)
    if (name === 'display-flex') {
      this.name = 'flex'
    }
  }
  ...
  prefixed (prefix) {
    let spec, value
        ;[spec, prefix] = flexSpec(prefix)
        // spec 为年份版本 prefix为浏览器前缀
    if (spec === 2009) {
      if (this.name === 'flex') {
        value = 'box'
      } else {
        value = 'inline-box'
      }
    } else if (spec === 2012) {
      if (this.name === 'flex') {
        value = 'flexbox'
      } else {
        value = 'inline-flexbox'
      }
    } else if (spec === 'final') {
      value = this.name
    }

    return prefix + value
  }
    ...
}

autoprefixer 会获取我们在 Postcss 中配置的需要支持的浏览器版本。我们的 css 文件里的内容已经被 Postcss 转换成 AST ,相应的就可以拿到属性名和属性值。在 autoprefixer 里面有很多属性的 hook ,当 AST 中有hooks 中的属性时,就会进到该属性的处理中,就会进行上面代码展示的进行属性名和属性值的转换,比如为该属性加上浏览器前缀。(应对不同浏览器厂商所支持的不同,只能进行很多的特判来进行兼容,可见 css 历史包袱有多重)。

总结

本文只是简单的使用了一下Postcss,还有许多不同的使用方法。

首先,Postcss 不是css预处理器的替代品,虽然可以替代。 其次,Postcss 是一个插件工具,丰富的插件生态意味着能够覆盖绝大多数的场景和业务。 最后,Postcss 优化了整个web开发流程,丢掉了历史包袱,强化了css的健壮性。

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhengddzz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值