跳到主要内容

插件

2025年01月14日
柏拉文
越努力,越幸运

一、认识


二、语法


PostCSS 插件本质上是一个函数,它接受一个 root 对象并返回一个修改后的 rootroot 对象代表 CSS 文件的 AST(抽象语法树),你可以在这个 AST 上进行各种操作。

PostCSS Plugin 结构: 通常是一个返回一个函数的模块,这个函数会接收 rootresult 两个参数: rootPostCSS 解析后的 AST,表示整个 CSS 文件的结构; resultPostCSS 的最终结果,可以用来保存生成的 CSS 或进行其他操作

const postcss = require('postcss');

module.exports = postcss.plugin('my-plugin', function(options) {
return function(root, result) {
// 插件逻辑:对 root (CSS AST) 进行操作
root.walkDecls(function(decl) {
// 例如:修改所有 CSS 属性名称
if (decl.prop === 'color') {
decl.value = 'red';
}
});
};
});
  • postcss.plugin(name, func):这是 PostCSS 用来定义插件的方式,name 是插件名称,func 是插件的实现。

  • root.walkDecls():这个方法遍历 CSS 中的所有声明(即每一行的 property: value)。

  • 在插件内部,你可以自由操作 root 对象,改变 CSS 文件的内容或结构

示例: 创建一个简单的 PostCSS 插件 - 将所有颜色值替换为红色: 这个插件会遍历 CSS 文件中的所有声明,查找 valueblue 的属性,并将其改为 red

const postcss = require('postcss');

module.exports = postcss.plugin('replace-color', function() {
return function(root) {
root.walkDecls(function(decl) {
if (decl.value === 'blue') {
decl.value = 'red'; // 将所有的 blue 改为 red
}
});
};
});

PostCSS Plugin 最佳实践:

  1. 避免修改原始 rootPostCSSrootCSS AST 的根,避免直接修改它。应通过 walkappend 等方法来安全地操作。

  2. 确保插件的幂等性:一个插件应该始终产生相同的输出,给定相同的输入。这意味着它应该根据输入生成输出,而不是修改全局状态。

  3. 考虑性能:对于大型项目或 CSS 文件,PostCSS 插件可能会遇到性能瓶颈。务必避免不必要的重复操作,合理利用 AST 操作。

  4. 编写文档:为了帮助其他开发者理解你的插件,应该写清楚插件的功能和使用方法。

三、文档


3.1 root.append()

3.1 root.walkDecls()

四、已有插件


4.1 cssnano

cssnano 插件 用于压缩 CSS 文件,减小文件体积。

4.2 autoprefixer

autoprefixer 自动为 CSS 添加浏览器前缀,使其兼容更多浏览器。

4.3 postcss-pxtorem

postcss-pxtorem 插件 用于将 CSS 中的 px 单位自动转换为 rem 单位,从而实现响应式布局。它是前端开发中非常常见的工具,尤其在移动端开发和使用 rem 单位来处理布局时特别有用。

postcss-pxtorem 语法:

module.exports = {
plugins: [
require('postcss-pxtorem')({
rootValue: 16, // 根元素字体大小,通常是 16px
propList: ['*'], // 要转换的属性列表,* 表示所有属性
unitPrecision: 5, // 转换后保留的小数点位数
selectorBlackList: [], // 不转换的 CSS 选择器
replace: true, // 是否直接替换原有的 px 单位
mediaQuery: false, // 是否转换媒体查询中的 px
minPixelValue: 0 // 小于此值的 px 单位不进行转换
})
]
};
  • rootValue: 设定根元素的字体大小。一般情况下,推荐设定为 16,因为浏览器默认的根字体大小通常是 16px,这样转换出来的 1rem 就等于 16px

  • propList: 你可以指定哪些 CSS 属性需要进行单位转换,* 表示所有属性都转换。如果只想转换某些特定的属性,可以传入一个数组(例如 ['font', 'padding'])。

  • unitPrecision: 设定转换后的 rem 小数点精度,默认为 5,表示保留 5 位小数。

  • selectorBlackList: 用来排除一些不需要转换的 CSS 选择器。例如,你可以设置 ['.no-rem'] 来避免这些类名下的 CSS 被转换。

  • replace: 是否直接替换原有的 px 单位,默认为 true

  • mediaQuery: 是否在媒体查询中进行单位转换,默认为 false,如果你想在媒体查询中也进行转换,可以设为 true。

  • minPixelValue: 转换 pxrem 时,px 的值低于这个数字的将不进行转换。默认值是 0,表示所有 px 单位都会被转换。

4.4 postcss-preset-env

postcss-preset-env 让你使用 CSS 的最新特性,自动转化为当前支持的特性。

4.5 postcss-px-to-viewport

postcss-px-to-viewport 是一个 PostCSS 插件,它的主要功能是将 CSS 中的 px 单位转换为视口单位(vwvh等),通常用于响应式设计和移动端适配。通过这个插件,你可以更方便地为不同屏幕尺寸的设备生成自适应的布局,而不需要手动去调整 CSS 文件中的每个 px 值。postcss-px-to-viewport 计算逻辑为: targetValue(最终要在代码中写的 vw 值) = UI 稿元素(尺寸、字体大小等) / UI 稿宽度 * 100(100vw 始终为屏幕尺寸)

module.exports = {
plugins: [
require('postcss-px-to-viewport')({
unitToConvert: 'px', // 需要转换的单位,默认为 px
viewportWidth: 375, // 设计稿的视口宽度(通常是设计师给定的标准宽度,例如 375px)
viewportHeight: 667, // 设计稿的视口高度(可选,用于特定场景)
unitPrecision: 5, // 转换后保留的小数位数
propList: ['*'], // 需要转换的属性列表,* 代表所有属性
viewportUnit: 'vw', // 转换后的单位,默认为 vw
fontViewportUnit: 'vw', // 字体使用的视口单位,默认为 vw
selectorBlackList: [], // 不需要转换的选择器(例如排除一些特定类名)
minPixelValue: 1, // 小于此值的 px 不进行转换
mediaQuery: false, // 是否在媒体查询中转换 px,默认为 false
exclude: [/node_modules/] // 排除某些文件夹或文件(可通过正则匹配)
})
]
};
  • unitToConvert: 要转换的单位,默认是 px,意味着它会把 px 转换成视口单位(如 vw)。

  • viewportWidth: 设计稿的宽度。通常情况下,这个值等于设计稿的宽度(比如 750px)。这个值决定了最终转换后 vw 单位的比例。例如,如果你设定 viewportWidth: 375,那么 1vw = 375px

  • viewportHeight: 可选项,用于指定设计稿的视口高度。如果设计稿中有基于高度的适配需求(如 vh),可以配置这个项。

  • unitPrecision: 转换后保留的小数位数。为了避免过度的小数导致的计算精度问题,可以设置合适的精度。通常,保留 5 位小数已经足够。

  • propList: 用来配置哪些属性的 px 值需要转换为视口单位。如果设置为 ['*'],意味着所有 px 单位都会转换。如果你只想转换某些特定的属性,可以在此配置,如 ['font', 'width', 'height']

  • viewportUnit: 转换后的单位。默认情况下,它会把 px 转换成 vw 单位。如果你希望它转换成 vhem,可以调整这个设置。

  • fontViewportUnit: 字体使用的视口单位,默认为 vw。这意味着字体的大小也会根据视口的宽度进行适配。如果你想为字体单独设置不同的单位,可以调整此项。

  • selectorBlackList: 需要排除的选择器。这里你可以指定不需要转换的选择器,防止某些特殊的 CSS 样式被转换。

  • minPixelValue: 小于此值的 px 不进行转换。默认值是 1,意味着小于 1pxpx 值不会被转换。这可以避免一些微小的元素(如边框)不必要的转换。

  • mediaQuery: 是否在媒体查询中也进行 px 到视口单位的转换。如果你希望在响应式设计中,媒体查询中的 px 单位也被转换,可以将该值设为 true

  • exclude: 用于排除某些文件或文件夹,通常是 node_modules 目录。这避免了对第三方库中的 CSS 文件进行不必要的转换。