前言
原谅我取这样的标题,我知道 postCss 对于大多数前端开发者来说早已经很熟悉了,但是楼主作为一个初出茅庐的前端er,还有好多的工具和技术没接触过,说来惭愧。虽然平时也喜欢使用css预处理器比如 sass、less、stylus,但是关于css的其他工具确实接触的少,postCss就是一个例子,于是今天就对它了解了一番。如果你对postCss也不是很了解,那么希望这篇博客可以帮助到你。
什么是 postCss?
postCss 不是什么新玩意,而是一个几年前就被广泛使用的工具。而且我们很可能已经无意或有意的使用到了它,我们通常说的 postCss 一般指两个方面:
- postCss 本身。
- postCss 衍生的生态系统,比如各种插件。
postCss 本身是一个JavaScript 模块,它会读取我们的css代码,然后将它们转化为一个 抽象语法树 (abstract syntax tree)。它还是一个插件系统,它提供了一些api,开发者可以基于这些 api 开发插件。
postCss 将我们的css代码转为抽象语法树后,我们可以使用各种的插件去实现各种的功能,最后会转化为字符串输出到一个文件中。这里的插件可以是已存在的插件,也可以是按自己需要自己定制的插件。
postCss 的定位
postCss 属于 预处理器 (preprocessor) 吗?还是属于 后置处理器 (postprocessor) ?都不是,因为 postCss 具体做的事取决于开发者使用了什么插件。它可以通过相应的插件去实现类似 sass 等预处理器的功能,如: precss;也可以通过相应的插件执行后置处理器的工作,如:autoprefixer。
这里做一个我觉得比较恰当的类比,css 中的 postCss 相当于 JavaScript 的 babel;css 中的 sass,less,stylus 等预处理器相当于 Typescript,虽然不是完全合理,但是还是比较恰当。
如何使用 postCss
其实我们很多时候都无意的使用到了 postCss,autoprefixer 就是一个例子,这个插件的功能就是自动的为我们的css代码加上对应的前缀,以便兼容更多的浏览器,很多脚手架都会使用到这个插件。postCss 如何使用呢?使用方法 总的来说就是根据自己的构建工具或生产环境进行对应的配置。以 webpack 为例:
// 使用postcss-loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 1,
}
},
{
loader: 'postcss-loader'
}
]
}
]
}
}
复制代码
// 建立对应的配置文件 postcss.config.js,使用对应的插件实现对应的功能。
module.exports = {
plugins: [
require('precss'),
require('autoprefixer')
]
}
复制代码
如何根据自己需要定制一个 postCss 插件?
虽然现在postCss的插件已经非常丰富了,但是有时候还是需要自己写一个插件来满足自己的需求,下面来逐步说一下如何自己定制一个postCss插件。
插件效果
处理前:
div {
color: mycolor
}
复制代码
处理后:
div {
color: crimson
}
复制代码
这个插件的功能就是将我们 css 文件中的 mycolor 变量替换为 赤红色 crimson。
准备
假设我们用的构建工具是 webpack。先简单的搭建一个webpack的工作环境:webpack 起步
// 新建文件夹 webpackStarterProject 然后运行
npm init -y
npm install --save-dev webpack webpack-cli
npm install --save-dev style-loader css-loader postcss-loader
复制代码
文件目录
// webpackStarterProject root path
node_modules
index.js
style.css
index.html
package.json
webpack.config.js
复制代码
然后 webpack.config.js 的配置与上面的配置基本一致。
const path = require('path')
// 使用postcss-loader
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 1,
}
},
{
loader: 'postcss-loader'
}
]
}
]
}
}
复制代码
index.js 文件加入以下代码:
// index.js
import './style.css';
复制代码
style.css 文件加入以下代码:
div {
color: mycolor
}
复制代码
index.html 文件加入以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>
what is my color ?
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
复制代码
到这里我们的工作环境搭建完毕,开始编写自己的postCss插件。
开始编写插件
通常情况下,我们使用第三方插件的时候,都是通过npm将第三方插件包下载到项目的node_modules中来使用,这里因为我们是自己编写插件,所以直接在 node_modules 中加入自己要编写的插件。在 node_modules 中新建文件夹 postcss-myplugin 来编写我们的插件。
// webpackStarterProject root path
node_modules
|--- postcss-myplugin
index.js
style.css
index.html
package.json
webpack.config.js
复制代码
进入postcss-myplugin 文件夹,运行以下命令:
npm init -y
npm install --save postcss
复制代码
在 postcss-myplugin 文件夹中新建一个 index.js,并加入一下代码:
const postcss = require('postcss');
// 使用 postcss.plugin 方法创建一个插件
module.exports = postcss.plugin('myplugin', function myplugin() {
return function (css) {
// 此插件的功能将在这里添加。
}
});
复制代码
然后在 webpackStarterProject 根目录下添加postcss配置文件 postcss.config.js:
module.exports = {
plugins: [
// 引用我们的插件
require('postcss-myplugin')
]
}
复制代码
当前主要文件结构为:
// webpackStarterProject root path
node_modules
|--- postcss-myplugin
|---node_modules
|---index.js
index.js
style.css
index.html
package.json
webpack.config.js
postcss.config.js
复制代码
接下来我们就可以继续去实现自己插件的功能了,postCss提供了一系列的 api 方便我们开发插件 PostCss Api。 给插件添加功能:
const postcss = require('postcss');
module.exports = postcss.plugin('myplugin', function myplugin() {
return function (css) {
css.walkRules(rule => {
// 遍历规则节点
rule.walkDecls((decl) => {
// 遍历声明节点
let value = decl.value;
if (value.indexOf('mycolor') != -1) {
// 将 mycolor 变量替换为 crimson
decl.value = value.replace('mycolor', 'crimson')
}
})
})
}
});
复制代码
大功告成!最后在package.json的script字段中添加以下命令:
"start": "webpack --config webpack.config.js"
复制代码
运行命令打包代码,在浏览器中查看效果:
npm start
复制代码
最后插件也可以再处理一下然后发布到npm上开源出去。
总结
- postCss 本身是一个nodejs module,用于转换css代码成一个抽象语法树,然后我们可以利用各种插件实现对css的各种操作。
- postCss 既不是预处理器也不是后置处理器,而是类似于babel的角色,做什么事情取决于使用了什么插件。
- 可以定制自己的插件,实现自己想要的功能。