postcss 单独不转换_如果你不会Postcss,那么你就真的不会Postcss

作者:张军

前言

说起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的健壮性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值