51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

如何使用PostCSS作为Sass的可配置替代

500.jpg

Web开发人员喜欢Sass CSS预处理程序。每一个开发人员都知道它是什么,89%经常使用它,而88%的高满意度。

许多Web捆绑程序都包含Sass处理,但是您可能在使用PostCSS时也没有意识到这一点。PostCSS主要以其Autoprefixer插件,其自动添加-webkit-moz-ms在需要时供应商前缀的CSS特性。它的插件系统意味着它可以做更多的事情,例如.scss无需使用Sass编译器即可编译文件。

本教程说明了如何创建自定义CSS预处理器,该预处理器可编译Sass语法并对其进行补充以提供更多功能。对于有特定CSS要求并且只懂一点Node.js的人来说,它是理想的选择。

快速开始

可以从GitHub克隆一个示例PostCSS项目。它需要Node.js,因此请运行npm install以获取所有依赖项。

编译演示src/scss/main.scss源代码以build/css/main.css使用:

npm run css:dev

每当使用以下命令更改文件时,自动编译:

npm run css:watch

然后按Ctrl|退出观看 Cmd+C在终端中。

这两个选项还在处创建了一个源映射build/css/main.css.map,该映射引用了开发人员工具中的原始源文件。

没有源映射的生产级最小化CSS可以使用以下命令进行编译:

npm run css:build

README.md有关更多信息,请参考文件。

您应该用PostCSS代替Sass吗?

Sass编译器没有任何问题,但请考虑以下因素。

模块依赖

可以使用Node.jsnpm软件包管理器在全球范围内安装Sass的最新Dart版本:

npm install -g sass

使用以下命令编译Sass.scss代码:

sass [input.scss] [output.css]

源映射是自动生成的(--no-source-map将其关闭),或者--watch可以在更改时将其添加到自动编译的源文件中。

最新版本的Sass需要少于5MB的安装空间。

PostCSS应该需要更少的资源,并且需要一个具有自动前缀的类似Sass的基本编译器,而压缩需要不到1MB的空间。实际上,您的node_modules文件夹将扩展到60MB以上,并随着添加更多插件而迅速增加。这主要是npm安装其他依赖项。即使PostCSS可能不使用它们,也不能将其视为轻量级替代方案。

但是,如果您已经将PostCSS用于自动前缀或其他用途,则可能不需要Sass。

处理速度

慢速的基于Ruby的Sass编译器早已消失,最新版本使用已编译的Dart运行时。它很快。

PostCSS是纯JavaScript,尽管基准会有所不同,但编译同一源代码的速度可能会慢三倍。

但是,如果您已经在Sass之后运行PostCSS,则这种速度差异将不太明显。两步过程可能比单独使用PostCSS慢,因为它的许多工作都涉及标记CSS属性。

客制化

Sass语言包含大量功能,包括变量,嵌套,部分,混合和更多功能。有缺点:

  1. 您无法轻松添加新功能。

    也许您想要将HSLA颜色转换为RGB的选项。可能可以编写自定义函数,但是其他要求将是不可能的,例如将SVG内联为背景图像。

  2. 您不能轻易限制功能集。

    也许您希望您的团队不要使用嵌套或@extend。整理规则会有所帮助,但不会停止Sass编译有效.scss文件。

PostCSS的可配置性更高。

PostCSS本身不执行任何操作。处理功能需要众多可用插件中的一个或多个。大多数执行单个任务,因此,如果您不想嵌套,请不要添加嵌套插件。如有必要,您可以在可以利用Node.js功能的标准JavaScript模块中编写自己的插件。

安装PostCSS

PostCSS可以与webpack,Parcel,Gulp.js和其他构建工具一起使用,但是本教程显示了如何从命令行运行它。

如有必要,请使用初始化一个新的Node.js项目npm init。通过安装以下用于基本.scss解析的模块来设置PostCSS,这些模块带有用于部分,变量,mixin,嵌套和自动前缀的插件:

npm install --save-dev postcss postcss-cli postcss-scss postcss-advanced-variables postcss-nested autoprefixer

与示例项目一样,PostCSS及其插件在本地安装。如果您的项目可能具有不同的编译要求,则这是一个实际的选择。

注意:PostCSS只能从JavaScript文件运行,但是该postcss-cli模块提供了可从命令行调用的包装器。该postcss-SCSS模块允许PostCSS读取.scss文件,但不改变它们。

自动前缀配置 {#autoprefixerconfiguration}

Autoprefixer使用浏览器列表根据支持的浏览器列表确定需要哪些供应商前缀。将此清单定义为中的"browserslist"数组是最简单的package.json。以下示例添加了供应商前缀,其中任何浏览器均具有至少2%的市场份额:

"browserslist": [
  "> 2%"],

您的第一个版本

通常,您将只有一个根Sass.scss文件,该文件可导入所有必需的部分/组件文件。例如:

// root Sass file// src/scss/main.scss@import '_variables';@import '_reset';@import 'components/_card';// etc.

可以通过运行npx postcss,输入文件,--output文件和所有必需的选项来启动编译。例如:

npx postcss ./src/scss/main.scss \
    --output ./build/css/main.css \
    --env development \
    --map \
    --verbose \
    --parser postcss-scss \
    --use postcss-advanced-variables postcss-nested autoprefixer

该命令:

  1. 解析 ./src/scss/main.scss

  2. 输出到 ./build/css/main.css

  3. NODE_ENV环境变量设置为development

  4. 输出外部源映射文件

  5. 设置详细的输出和错误消息

  6. 设置postcss-scssSass解析器,并

  7. 使用插件postcss-advanced-variablespostcss-nested以及autoprefixer处理谐音,变量,混入,嵌套,和自动前缀

(可选)您可以在修改文件后添加--watch到自动编译.scss

创建一个PostCSS配置文件

对于较长的插件列表,命令行很快变得难以处理。您可以将其定义为npm脚本,但是PostCSS配置文件是一个更简单的选项,它提供了更多的可能性。

PostCSS配置文件是命名为JavaScript模块的文件postcss.config.js,通常存储在项目的根目录(或运行PostCSS的目录)中。该模块必须export具有一个功能:

// postcss.config.jsmodule.exports = cfg => {
  // ... configuration ...};

它传递了一个cfg具有postcss命令设置属性的对象。例如:

{
  cwd: '/home/name/postcss-demo',
  env: 'development',
  options: {
    map: undefined,
    parser: undefined,
    syntax: undefined,
    stringifier: undefined
  },
  file: {
    dirname: '/home/name/postcss-demo/src/scss',
    basename: 'main.scss',
    extname: '.scss'
  }}

您可以检查这些属性并做出相应的反应-例如,确定您是否在development模式下运行并处理.scss输入文件:

// postcss.config.jsmodule.exports = cfg => {
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  // ... configuration ...};

该函数必须返回一个属性名称与postcss-cli命令行选项匹配的对象。以下配置文件复制了上面使用的long quick start命令:

// postcss.config.jsmodule.exports = cfg => {
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  return {
    map: dev ? { inline: false } : false,
    parser:  scss ? 'postcss-scss' : false,
    plugins: [
      require('postcss-advanced-variables')(),
      require('postcss-nested')(),
      require('autoprefixer')()
    ]
  };};

现在可以使用较短的命令运行PostCSS:

npx postcss ./src/scss/main.scss \
    --output ./build/css/main.css \
    --env development \
    --verbose

以下是一些注意事项:

  • --verbose是可选的:未在中设置postcss.config.js

  • Sass语法分析仅在输入是.scss文件时才应用。否则,它默认为标准CSS。

  • 仅当--env设置为时,才输出源映射development

  • --watch 仍可以添加以进行自动编译。

如果您希望postcss.config.js位于另一个目录中,则可以使用--config-进行引用--config /mycfg/。在示例项目中,上面的配置位于中config/postcss.config.js。通过运行引用npm run css:basic,它调用:

npx postcss src/scss/main.scss \
    --output build/css/main.css \
    --env development \
    --verbose \
    --config ./config/

添加更多插件

以下各节提供了PostCSS插件的示例,这些CSS插件可以解析其他.scss语法或提供超出Sass编译器范围的处理。

使用设计令牌

设计令牌是一种与技术无关的方法,用于存储诸如公司范围内的字体,颜色,间距等变量。您可以将令牌名称/值对存储在JSON文件中:

{
  "font-size": "16px",
  "font-main": "Roboto, Oxygen-Sans, Ubuntu, sans-serif",
  "lineheight": 1.5,
  "font-code": "Menlo, Consolas, Monaco, monospace",
  "lineheight-code": 1.2,
  "color-back": "#f5f5f5",
  "color-fore": "#444"}

然后在任何Web,Windows,macOS,iOS,Linux,Android或其他应用程序中引用它们。

Sass不直接支持设计令牌,但是variables可以将具有名称/值对属性的JavaScript对象传递给现有的postcss-advanced-variables PostCSS插件:

// PostCSS configurationmodule.exports = cfg => {
  // import tokens as Sass variables
  const variables = require('./tokens.json'); // NEW
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  return {
    map: dev ? { inline: false } : false,
    parser:  scss ? 'postcss-scss' : false,
    plugins: [
      require('postcss-advanced-variables')({ variables }), // UPDATED
      require('postcss-nested')(),
      require('autoprefixer')()
    ]
  };};

该插件将所有值转换为全局Sass $variables,可在任何局部使用。可以设置后备值以确保即使变量中缺少变量也可用tokens.json。例如:

// set default background color to #FFF// if no "color-back" value is set in tokens.json$color-back: #fff !default;

然后可以在任何.scss文件中引用令牌变量。例如:

body {
  font-family: $font-main;
  font-size: $font-size;
  line-height: $lineheight;
  color: $color-fore;
  background-color: $color-back;}

示例项目中token.json定义了一个文件,该文件在运行时被加载和使用npm run css:dev

添加Sass Map支持

Sass Maps是键值对象。该map-get函数可以按名称查找值。

下面的示例将媒体查询断点定义为带有respondmixin的Sass映射,以获取命名值:

// media query breakpoints$breakpoint: (
  'small':  36rem,
  'medium': 50rem,
  'large':  64rem);/*
responsive breakpoint mixin:
@include respond('medium') { ... }
*/@mixin respond($bp) {
  @media (min-width: map-get($breakpoint, $bp)) {
    @content;
  }}

然后可以在同一选择器中定义默认属性和媒体查询修改。例如:

main {
  width: 100%;
  @include respond('medium') {
    width: 40em;
  }}

哪个可以编译成CSS:

main {
  width: 100%;}@media (min-width: 50rem) {
  main {
    width: 40em
  }}

postcss-MAP-GET插件添加萨斯地图处理。通过以下方式安装:

npm install --save-dev postcss-map-get

并更新postcss.config.js配置文件:

// PostCSS configurationmodule.exports = cfg => {
  // import tokens as Sass variables
  const variables = require('./tokens.json');
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  return {
    map: dev ? { inline: false } : false,
    parser:  scss ? 'postcss-scss' : false,
    plugins: [
      require('postcss-advanced-variables')({ variables }),
      require('postcss-map-get')(), // NEW
      require('postcss-nested')(),
      require('autoprefixer')()
    ]
  };};

添加媒体查询优化

由于我们已经添加了媒体查询,因此将它们组合并按移动优先顺序进行排序将非常有用。例如,以下CSS:

@media (min-width: 50rem) {
  main {
    width: 40em;
  }}@media (min-width: 50rem) {
  #menu {
    width: 30em;
  }}

可以合并成为:

@media (min-width: 50rem) {
  main {
    width: 40em;
  }
  #menu {
    width: 30em;
  }}

这在Sass中是不可能的,但是可以通过PostCSS postcss-sort-media-queries插件来实现。通过以下方式安装:

npm install --save-dev postcss-sort-media-queries

然后将其添加到postcss.config.js

// PostCSS configurationmodule.exports = cfg => {
  // import tokens as Sass variables
  const variables = require('./tokens.json');
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  return {
    map: dev ? { inline: false } : false,
    parser:  scss ? 'postcss-scss' : false,
    plugins: [
      require('postcss-advanced-variables')({ variables }),
      require('postcss-map-get')(),
      require('postcss-nested')(),
      require('postcss-sort-media-queries')(), // NEW
      require('autoprefixer')()
    ]
  };};

添加资产处理

资产管理在Sass中不可用,但是postcss-assets使它变得容易。该插件可解析CSS图像URL,添加缓存清除功能,定义图像尺寸,并使用base64表示法内联文件。例如:

#mybackground {
  background-image: resolve('back.png');
  width: width('back.png');
  height: height('back.png');
  background-size: size('back.png');}

编译为:

#mybackground {
  background-image: url('/images/back.png');
  width: 600px;
  height: 400px;
  background-size: 600px 400px;}

使用以下命令安装插件:

npm install --save-dev postcss-assets

然后将其添加到中postcss.config.js。在这种情况下,将指示插件在src/images/目录中找到图像:

// PostCSS configurationmodule.exports = cfg => {
  // import tokens as Sass variables
  const variables = require('./tokens.json');
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  return {
    map: dev ? { inline: false } : false,
    parser:  scss ? 'postcss-scss' : false,
    plugins: [
      require('postcss-advanced-variables')({ variables }),
      require('postcss-map-get')(),
      require('postcss-nested')(),
      require('postcss-sort-media-queries')(),
      require('postcss-assets')({   // NEW
        loadPaths: ['src/images/']
      }),
      require('autoprefixer')()
    ]
  };};

添加缩小

cssnano设置CSS缩小的标准。缩小可能比其他插件花费更多的处理时间,因此只能在生产中使用。

使用以下命令安装cssnano:

npm install --save-dev cssnano

然后将其添加到中postcss.config.js。在这种情况下,仅当NODE_ENV设置为以外的其他值时,才会发生缩小development

// PostCSS configurationmodule.exports = cfg => {
  // import tokens as Sass variables
  const variables = require('./tokens.json');
  const
    dev = cfg.env === 'development',
    scss = cfg.file.extname === '.scss';
  return {
    map: dev ? { inline: false } : false,
    parser:  scss ? 'postcss-scss' : false,
    plugins: [
      require('postcss-advanced-variables')({ variables }),
      require('postcss-map-get')(),
      require('postcss-nested')(),
      require('postcss-sort-media-queries')(),
      require('postcss-assets')({
        loadPaths: ['src/images/']
      }),
      require('autoprefixer')(),
      dev ? null : require('cssnano')() // NEW
    ]
  };};

设置--envprodution触发器缩小(并移除源映射):

npx postcss ./src/scss/main.scss \
    --output ./build/css/main.css \
    --env prodution \
    --verbose

在示例项目中,可以通过运行来编译生产CSS npm run css:build

进步到PostCSS?

PostCSS是功能强大且可配置的工具,可以编译.scss文件并增强(或限制)标准的Sass语言。如果您已经使用PostCSS作为Autoprefixer,则可以在保留您喜欢的语法的同时完全删除Sass编译器。

赞(0)
未经允许不得转载:工具盒子 » 如何使用PostCSS作为Sass的可配置替代