PostCSS介绍

1,326 阅读10分钟

CSS预处理程序很流行,但是它们也有一些缺点。在这篇关于PostCSS的介绍中,我们将探讨PostCSS的优势,它是如何工作的,以及它的大量插件可以实现什么。

Processing CSS with PostCSS

预处理器的价值和局限性

大多数CSS开发者都熟悉预处理程序。包括Sass、Less和Stylus在内的工具引入了诸如文件参数、嵌套、变量和混合器等概念。一些功能正逐渐出现在本地CSS中,但预处理器对于管理大型代码库和保持风格和编码的一致性仍然很有用。

可能很难想象没有CSS预处理器的生活,但也有缺点:

  • 预处理器是不可扩展的或者说是限制的. 大多数预处理器是一个黑盒子,为你提供一组特定的支持功能。也许可以编写自定义函数,但超出该工具范围的功能仍然是不可能的—比如内联SVG作为背景图片。

    同样地,你也无法阻止开发者使用你宁愿避免的选项,如 @extend 或深度嵌套。语法分析可以提供帮助,但它不能阻止预处理器编译一个有效的文件。

  • 预处理器提供他们自己的语法。预处理器的代码可能类似于CSS,但没有浏览器可以原生解析该文件。语法是不同的,如果你的工具发生变化或不可用,你的代码将需要更新以使其可用。

    这样做的好处超过了这些风险,但有一个替代方法......

PostCSS是什么?

PostCSS不是一个预处理器(尽管它的行为很像)。 它是一个Node.js工具,它采用有效的CSS并对其进行增强。即使是那些使用Sass、Less或Stylus的人,也经常在初始CSS编译后运行PostCSS步骤。你可能遇到过PostCSS的Autoprefixer插件 ,它可以在需要前缀的CSS属性中自动添加 -webkit, -moz, and -ms 前缀。

就其本身而言,PostCSS什么也不做。它是一个对CSS代码进行标记以创建抽象语法树的解析器。一个插件可以处理这个树并相应地更新属性。一旦所有插件完成了它们的工作,PostCSS将所有内容重新格式化为字符串并输出到CSS文件中。

大约有 350 个插件可用,大多数都是执行单一的任务,如 代码嵌入 @import 声明简化 calc() 函数处理图片资源语法提示压缩等等。 在PostCSS的插件目录中,有一个更方便用户的插件搜索。

PostCSS 优势包含如下:

  • **你可以从标准的CSS开始。**PostCSS对CSS的作用就像Babel对JavaScript一样。它可以使用一个在最近的浏览器中有效的标准样式表,并输出在任何地方都有效的CSS — 例如,将较新的 inset 属性转变成top, bottom, leftright属性。随着时间的推移,你可以放弃这个过程,因为越来越多的浏览器支持inset

    不可否认,有些插件允许你解析类似于预处理程序的语法,这不是标准的CSS,但你不一定要使用它们。

  • **使用你需要的插件和功能。**PostCSS是可配置的,你可以采用你需要的插件。例如,你可以支持局部导入嵌套,但不允许变量、循环、混合、映射和其他Sass中的功能。

  • **为每个项目提供一个自定义的配置。**一个单独的项目配置可以加强或减少其他地方使用的插件集。这些选项远比任何预处理程序要多得多。

  • **编写你自己的PostCSS插件。**大量的插件可用于扩展语法、解析未来的属性、添加回退、优化代码、处理颜色、图像、字体,甚至可以用其他语言编写CSS,如西班牙语俄语

    万一你找不到你需要的东西,你可以用JavaScript编写自己的PostCSS插件。

  • **你可能已经在使用PostCSS了。**如果你已经在运行了PostCSS插件,如AutoPrefixer,你就可以移除你的预处理器依赖项。PostCSS不一定比使用预处理器更快、更轻,但它可以在一个步骤中处理所有的CSS处理。

安装PostCSS

PostCSS需要Node.js,但本教程演示了如何从任何文件夹中安装和运行PostCSS--甚至那些不是Node.js的项目。你也可以从 webpack、 Parcel、Gulp.js 和 其它工具中使用PostCSS,但我们将坚持使用命令行。

通过运行以下程序在你的系统中全局安装PostCSS。

npm install -g postcss-cli

通过输入这个确保它正在工作:

postcss --help

安装你的第一个PostCSS插件

您将需要至少一个插件来执行任何实际操作。PostCSS import插件是一个很好的选择,它内联所有的@import声明并将你的CSS合并到一个文件中。像这样全局安装它:

npm install -g postcss-import

为了测试这个插件,打开或创建一个新的项目文件夹,比如 cssproject,然后为你的源文件创建一个 src 子文件夹。创建一个 main.css 文件来加载所有部分:

/* src/main.css */
@import '_reset';
@import '_elements';

然后在同一个文件夹中创建一个 reset.css 文件:

/* src/reset.css */
* {
  padding: 0;
  margin: 0;
}

接下来是一个 elements.css 文件:

/* src/elements.css */
body {
  font-family: sans-serif;
}

label {
  user-select: none;
}

通过传递输入的CSS文件、要使用的 插件列表和 要输出 文件名,从项目的根目录下运行PostCSS。

postcss ./src/main.css --use postcss-import --output ./styles.css

如果没有任何错误,下面的代码将输出到项目根目录下的一个新的 styles.css 文件中:

/* src/main.css */
/* src/reset.css */
* {
  padding: 0;
  margin: 0;
}
/* src/elements.css */
body {
  font-family: sans-serif;
}
label {
  user-select: none;
}
/* sourceMappingURL=data:application/json;base64,...

注意PostCSS可以在任何地方输出CSS文件,但是输出文件夹必须存在;它不会为您创建文件夹结构。

启用和禁用源映射

默认情况下,会输出一个内联源码映射。当编译后的CSS文件被用于HTML页面时,在浏览器的开发工具中检查它将显示原始的 src 文件和行。例如,查看 <body> 样式将高亮显示 src/_elements.css 第2行,而不是 style.css 第8行。

你可以通过在 postcss 命令中添加 -map(或-m1)开关来创建一个外部源码图。除了CSS文件更干净,而且浏览器不需要加载源码图之外,没有什么好处,除非开发者工具是开放的。

你可以用 --no-map 删除源码图。在为生产部署输出CSS文件时,一定要使用这个选项。

安装和使用AutoPrefixer插件

Autoprefixer 插件通常是开发者第一次接触PostCSS的地方。它根据浏览器的使用情况和caniuse.com上定义的规则添加前缀。前缀在现代浏览器中使用较少,它们将实验性功能隐藏在标志后面。然而,仍有一些属性,如user-select,需要 -webkit--moz--ms- 前缀。

使用如下命令在全局范围内安装该插件:

npm install -g autoprefixer

Then reference it as another --use option on your postcss command:

然后在 postcss 命令上引用它作为另一个--use选项:

postcss ./src/main.css --use postcss-import --use autoprefixer --output ./styles.css

检查 styles.css 第11行中的 label 声明,以查看带有前缀的属性:

label {
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

AutoPrefixer使用 browserlist 模块来确定要添加哪些浏览器前缀。默认为:

  • > 0.5%: 拥有至少0.5%市场份额的浏览器
  • last 2 versions:这些浏览器的最后两个版本
  • Firefox ESR: 包括Firefox扩展支持的版本
  • not dead:任何未停止使用的浏览器

您可以通过创建 .browserslistrc 文件来更改这些默认值。例如:

> 2%

或者您可以在Node.js项目中添加 “browserslist” 数组到 package.json中。例如:

"browserslist": [
   "> 2%"
]

针对2%或更多市场份额的浏览器只需要Safari中的 -webkit- 前缀:

label {
  -webkit-user-select: none;
          user-select: none;
}

使用cssnano压缩CSS

cssnano通过去除空格、注释和其他不必要的字符来缩小CSS。结果会有所不同,但您可以预期减少30%的文件,您可以部署到生产服务器,以获得更好的网页性能。

全局安装cssnano:

npm install -g cssnano

然后将其添加到 postcss 命令中。我们还将包括 ——no-map 来禁用源映射:

postcss ./src/main.css --use postcss-import --use autoprefixer --use cssnano --no-map --output ./styles.css

这将CSS文件减少到97个字符:

*{margin:0;padding:0}body{font-family:sans-serif}label{-webkit-user-select:none;user-select:none}

当源文件更改时自动构建

当任何源文件更改时,PostCSS的——watch 选项会自动构建CSS文件。您可能还需要添加 ——verbose 开关,以便在生成时报告:

postcss ./src/main.css --use postcss-import --use autoprefixer --use cssnano --no-map --output ./styles.css --watch --verbose

您的终端将显示 等待文件更改。对任何文件进行更改,styles.css 将重新构建。PostCSS还会报告问题,比如语法错误。

在终端按Ctrl | Cmd + C 完成。

创建PostCSS配置文件

当你添加更多的插件和选项时,postcss 命令会变得又长又麻烦。您可以创建一个JavaScript配置文件,该文件定义了所有选项,并可以符合逻辑地确定它是在开发环境中运行还是在生产环境中运行。在项目文件夹的根目录下创建一个名为 postcss.config.cjs 的配置文件。请注意以下几点:

  • 当运行 postcss 命令时,你可以把文件放在另一个文件夹,但你需要指定 --config <dir>
  • 你可以使用 postcss.config.js 作为文件名,但 PostCSS 可能在Node.js项目的 package.json 中设置有 "type": "module"

将以下代码添加到 postcss.config.cjs 中:

// PostCSS configruation
module.exports = (cfg) => {

  const devMode = (cfg.env === 'development');

  return {

    map: devMode ? 'inline' : null,
    plugins: [
      require('postcss-import')(),
      require('autoprefixer')(),
      devMode ? null : require('cssnano')()
    ]

  };

};

PostCSS通过包含命令行选项的 cfg 对象。例如:

{
  cwd: '/home/yourname/cssproject',
  env: undefined,
  options: {
    map: { inline: true },
    parser: undefined,
    syntax: undefined,
    stringifier: undefined
  },
  file: {
    dirname: '/home/yourname/cssproject/src',
    basename: 'main.css',
    extname: '.css'
  }
}

模块必须返回一个具有可选属性的对象:

  • map:源映射设置
  • parser: 是否使用非CSS语法解析器(例如scss插件)
  • plugins: 一系列插件和配置以指定的顺序处理

上面的代码会检测 postcss 命令是否有一个 --env 选项。这是设置 NODE_ENV 环境变量的一个快捷方式。要在开发模式下编译CSS,请在运行 postcss 时使用 --env development,并且可以选择设置 --watch --verbose。这将创建一个内联的源码映射,并且不对输出进行压缩。

postcss ./src/main.css --output ./styles.css --env development --watch --verbose

要在生产模式下运行并在没有源映射的情况下编译精简的CSS,可以使用这个:

postcss ./src/main.css --output ./styles.css

理想情况下,您可以将它们作为终端命令或 npm 脚本运行,以进一步减少输入工作量。

Postcss的发展

现在您已经了解了PostCSS的基础知识。增强功能需要添加和配置更多的插件。花些时间,你很快就会有一个适合任何web项目的工作流。

关于如何使用PostCSS作为Sass的可配置选项的教程提供了更多的配置示例和插件选项。

有关地址: