浏览器兼容CSS处理之PostCSS
什么是PostCSS
PostCSS 是一个用 JavaScript 工具和插件转换 CSS 代码的工具。即提供了一种方式用JavaScript代码来处理CSS。利用PostCSS可以实现一些工程化的操作,如:自动添加浏览器前缀,代码合并,代码压缩等。
PostCSS 接收一个 CSS 文件并提供了一个 API 来分析、修改它的规则(通过把 CSS 规则转换成一个抽象语法树的方式)。在这之后,这个 API 便可被许多插件利用来做有用的事情,比如寻错或自动添加 CSS vendor 前缀。
安装
npm install --save-dev postcss postcss-cli
于Webpack中应用
安装postcss-loader
npm install --save-dev postcss-loader
安装autoprefixer
autoprefixer是PostCSS插件,用于解析CSS并使用Can I Use中的值为CSS规则添加供应商前缀。针对浏览器添加相应可兼容的CSS。
npm install --save-dev autoprefixer
安装postcss-preset-env
PostCSS预置环境可以让你将现代CSS转换成大多数浏览器都能理解的CSS,根据你的目标浏览器或运行时环境来决定你需要的CSS。
npm install postcss-preset-env --save-dev
在 webpack.config.js
里使用 postcss-loader
:
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
mode: "development",
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules$/,
use: ["style-loader", "css-loader", "postcss-loader"],
},
{
test: /\.less$/,
exclude: /node_modules$/,
use: ["style-loader", "css-loader","postcss-loader","less-loader"],
},
],
},
};
创建 postcss.config.js
:
module.exports = {
plugins: [/* require("autoprefixer"), */ require("postcss-preset-env")],
};
示例针对下面一段代码:
.title-1 {
display: grid;
transition: all .5s;
user-select: none;
background: linear-gradient(to bottom, white, black);
}
未使用postcss工具处理的打包结果:
可以看出CSS无甚变化;
使用postcss工具处理的打包结果:
显而易见,CSS做了响应浏览器兼容处理。兼容范围可以由.browserslistrc
工具的配置来控制。本次范围如下:
post-loader未处理@import文件
到目前为止postcss好像可以对项目的样式文件进行处理,但是对于@import导入的CSS,postcss-loader为进行处理。
如下:
/* test.css*/
.title {
display: grid;
transition: all 0.5s;
user-select: none;
background: linear-gradient(to bottom, white, black);
}
/* index.css*/
@import "./test.css";
.title-1 {
display: grid;
transition: all 0.5s;
user-select: none;
background: linear-gradient(to bottom, white, black);
}
打包结果:
结论:CSS未兼容容浏览器。
该现象原因:postcss-loader处理完css文件就交给css-loader去处理,css-loader处理完@import内容就交给下一个loader处理了,未交给上一个postcss-loader处理css内容。
对此现象可利用css-loader的importLoaders
配置项。
importLoaders作用:
-
允许为
@import
样式规则、CSS 模块或者 ICSS 启用/禁用或设置在 CSS loader 之前应用的 loader 的数量,例如:@import
/composes
/@value value from './values.css'
等。 -
importLoaders
选项允许你配置在css-loader
之前有多少 loader 应用于@import
ed 资源与 CSS 模块/ICSS 导入。
如下配置,再次打包:
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
mode: "development",
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
// 0 => no loaders (default);
// 1 => postcss-loader;
},
},
"postcss-loader",
],
},
{
test: /\.less$/,
exclude: /node_modules$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2,
// 0 => no loaders (default);
// 1 => postcss-loader;
// 2 => postcss-loader, less-loader
},
},
"postcss-loader",
"less-loader",
],
},
],
},
};
从上图可看出,postcss-loader处理了@import的css内容。