For AI agents: the complete documentation index is available at https://rspack.rs/zh/llms.txt, the full documentation bundle is available at https://rspack.rs/zh/llms-full.txt, and this page is available as Markdown at https://rspack.rs/zh/guide/builtin-loaders/lightningcss-loader.md.
close

Lightning CSS loader

Lightning CSS 是一个基于 Rust 编写的高性能 CSS 解析、转译和压缩工具。它支持将许多现代的 CSS 特性解析并转化为指定浏览器支持的语法,并提供更好的压缩比例。

Rspack 提供了一个内置的 builtin:lightningcss-loader,它基于 Lightning CSS 来转换 CSS,可以替代 postcss-loader 和 autoprefixer 的 CSS 语法降级、添加前缀等功能,并提供更好的性能。

Warning

请注意,Lightning CSS 严格要求输入的代码符合 CSS 规范。使用 builtin:lightningcss-loader 处理非标准 CSS 代码时,可能导致样式被忽略或产生不可预期的结果(未定义的行为)。为确保样式正确应用,请避免使用非标准 CSS 语法或特定浏览器的私有语法,而应采用符合 W3C 规范的标准 CSS 写法。

示例

如果需要在项目中使用 builtin:lightningcss-loader,需进行如下配置。

rspack.config.mjs
import { rspack } from '@rspack/core';

export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'builtin:lightningcss-loader',
            options: {
              targets: 'ie 10',
            },
          },
          // ... other loader
        ],
      },
    ],
  },
};

类型声明

你可以使用 @rspack/core 导出的 LightningcssLoaderOptions 类型来开启类型提示:

rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'builtin:lightningcss-loader',
            /** @type {import('@rspack/core').LightningcssLoaderOptions} */
            options: {
              targets: 'ie 10',
            },
          },
          // ... other loader
        ],
      },
    ],
  },
};

选项

下面是 builtin:lightningcss-loader 支持的配置。详细的解释请查看 lightningcss 文档

type LightningcssFeatureOptions = {
  nesting?: boolean;
  notSelectorList?: boolean;
  dirSelector?: boolean;
  langSelectorList?: boolean;
  isSelector?: boolean;
  textDecorationThicknessPercent?: boolean;
  mediaIntervalSyntax?: boolean;
  mediaRangeSyntax?: boolean;
  customMediaQueries?: boolean;
  clampFunction?: boolean;
  colorFunction?: boolean;
  oklabColors?: boolean;
  labColors?: boolean;
  p3Colors?: boolean;
  hexAlphaColors?: boolean;
  spaceSeparatedColorNotation?: boolean;
  fontFamilySystemUi?: boolean;
  doublePositionGradients?: boolean;
  vendorPrefixes?: boolean;
  logicalProperties?: boolean;
  selectors?: boolean;
  mediaQueries?: boolean;
  color?: boolean;
};

type Targets = {
  android?: string;
  chrome?: string;
  edge?: string;
  firefox?: string;
  ie?: string;
  ios_saf?: string;
  opera?: string;
  safari?: string;
  samsung?: string;
};

type LightningcssLoaderOptions = {
  minify?: boolean;
  errorRecovery?: boolean;
  targets?: string[] | string | Targets;
  include?: LightningcssFeatureOptions;
  exclude?: LightningcssFeatureOptions;
  drafts?: Drafts;
  nonStandard?: NonStandard;
  pseudoClasses?: PseudoClasses;
  unusedSymbols?: string[];
};

targets

  • 类型: string | string[] | Targets

browserslist 查询字符串或指定浏览器版本的 Targets 对象。

默认目标浏览器

未设置 targets 时,loader 会根据 Rspack 的 target 确定需要兼容的浏览器。例如,如果 target 为 browserslist 或 browserslist:modern,loader 就会使用相应的浏览器配置,无需重复设置。Lightning CSS 只支持浏览器环境,因此无法继承 node 等非浏览器 target。

即使没有显式设置 Rspack 的 target,loader 也会尝试继承它的默认值,详见 target 的默认行为。

如果没有设置 target,也找不到 Browserslist 配置,Rspack 就会使用默认值 web。由于 web 不包含浏览器版本信息,loader 不会自动设置 targets,需要时可以手动配置。

下面是一些 targets 的用法示例。

  • 设置 browserslist 查询字符串:
const loader = {
  loader: 'builtin:lightningcss-loader',
  /** @type {import('@rspack/core').LightningcssLoaderOptions} */
  options: {
    targets: 'ie 10',
  },
};
  • 设置 browserslist 查询字符串数组:
const loader = {
  loader: 'builtin:lightningcss-loader',
  /** @type {import('@rspack/core').LightningcssLoaderOptions} */
  options: {
    targets: ['chrome >= 87', 'edge >= 88', '> 0.5%'],
  },
};
  • 设置 Targets 对象:
const loader = {
  loader: 'builtin:lightningcss-loader',
  /** @type {import('@rspack/core').LightningcssLoaderOptions} */
  options: {
    targets: {
      chrome: '95.0',
      safari: '13.2',
    },
  },
};

errorRecovery

  • 类型: boolean
  • 默认值: true

控制 Lightning CSS 如何处理无效的 CSS 语法。

默认情况下启用,这意味着当 Lightning CSS 解析到无效的 CSS 规则或声明时,它会跳过这些内容,并输出警告,同时将这些无效部分从最终产物中移除,而不会中断编译过程。

忽略警告

如果你确认这些警告可以忽略,可以使用 ignoreWarnings 过滤掉来自 LightningCSS 的提示。

比如忽略所有警告:

rspack.config.mjs
export default {
  ignoreWarnings: [
    (warning) => /LightningCSS parse warning/.test(warning.message),
  ],
};

你也可以使用正则表达式来忽略特定的警告。

关闭 errorRecovery

如果将 errorRecovery 设置为 false,Lightning CSS 在解析任何无效的 CSS 语法时,都会抛出编译错误并中断构建过程:

rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'builtin:lightningcss-loader',
            /** @type {import('@rspack/core').LightningcssLoaderOptions} */
            options: {
              errorRecovery: false,
            },
          },
        ],
      },
    ],
  },
};

drafts

  • 类型: { customMedia?: boolean }
  • 默认值: undefined

启用草案 CSS 语法的解析。

将 drafts.customMedia 设为 true 可以解析 @custom-media 规则。当设置了 include.customMediaQueries 或配置了浏览器 targets 时,loader 会展开自定义媒体查询的引用,并移除对应的定义。由于 Lightning CSS 认为所有浏览器都不支持自定义媒体查询,任何浏览器 targets 都会启用该转换,包括从 Rspack 的 target 推导出的 targets。设置 exclude.customMediaQueries 可以保持自定义媒体查询不变。由于 include 的优先级高于 exclude,且 include.mediaQueries 已包含 include.customMediaQueries,因此只有在 include.customMediaQueries 和 include.mediaQueries 都未启用时,该设置才会生效。

例如,在设置 drafts: { customMedia: true } 和 include: { customMediaQueries: true } 后,以下 CSS:

@custom-media --wide (min-width: 800px);

@media (--wide) {
  .example {
    color: red;
  }
}

会被转换为:

@media (width >= 800px) {
  .example {
    color: red;
  }
}

自定义媒体查询在每个 CSS 文件内单独解析。如果某个文件使用了自身没有定义的名称,loader 会发出警告,并保留该文件中的所有自定义媒体查询不变。定义之间存在循环引用时,构建会报错。Lightning CSS 不会展开 @import 条件中的自定义媒体查询,因此如果某个文件在 @import 条件中使用了自定义媒体查询,loader 同样会保留该文件中的所有自定义媒体查询。

在文件之间共享自定义媒体查询

如果需要在多个文件中使用相同的定义,可以在该 loader 运行之前把它们添加到每个文件中。例如,使用一个追加共享文件的简单 loader:

custom-media-loader.mjs
import fs from 'node:fs/promises';
import path from 'node:path';

const definitions = path.resolve(import.meta.dirname, 'src/breakpoints.css');

export default async function loader(source) {
  this.addDependency(definitions);
  return `${source}\n${await fs.readFile(definitions, 'utf-8')}`;
}
rspack.config.mjs
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        type: 'css',
        use: [
          {
            loader: 'builtin:lightningcss-loader',
            options: {
              drafts: { customMedia: true },
              include: { customMediaQueries: true },
            },
          },
          './custom-media-loader.mjs',
        ],
      },
    ],
  },
};

this.addDependency() 会在共享定义变化时重新构建每个文件。定义可以出现在使用它们的查询之后,因此追加到末尾可以让 @import 规则保持在最前面,也不会改变 source map 中的位置。追加的定义会覆盖文件中的同名定义。

另一种方式是交给 LightningCssMinimizerRspackPlugin 处理,它会在每个输出的 CSS 文件范围内解析自定义媒体查询。在插件中启用 minimizerOptions.drafts.customMedia,并在该 loader 中保持 drafts.customMedia 关闭或在 include.customMediaQueries 和 include.mediaQueries 都未启用的情况下设置 exclude.customMediaQueries,使 loader 保留这些定义。这样自定义媒体查询只会在压缩后的产物中展开,并且每个名称都必须与使用它的查询位于同一个输出文件中。