npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

postcss-rule-unit-converter

v0.2.2

Published

Convert CSS units with composable PostCSS rules and built-in presets.

Readme

postcss-rule-unit-converter

基于规则的通用 PostCSS 单位转换插件。

特性

  • 一个插件统一处理 rpxpxremvwvh 以及自定义单位
  • 按规则顺序匹配转换
  • 内置常见单位的双向 preset
  • 复用仓库里现有的属性过滤、选择器黑名单、文件排除等能力
  • 同时支持单个 preset 和按场景封装好的 preset group

心智模型

  • 每条规则负责匹配一种源单位并生成一个新值。
  • 规则按顺序执行。
  • 如果多条规则都能命中同一个源单位,先写的那条优先。
  • 需要组合多组 preset 和自定义规则时,用 composeRules(...) 明确最终顺序。

用法

import postcss from 'postcss'
import unitConverter, { composeRules, presets } from 'postcss-rule-unit-converter'

const result = await postcss([
  unitConverter({
    rules: composeRules(
      presets.remToViewport({ viewportWidth: 375 }),
      presets.pxToRem({ rootValue: 16 }),
    ),
  }),
]).process('.title{font-size:1rem;margin:16px}', { from: undefined })

分组 Preset

import postcss from 'postcss'
import unitConverter, { composeRules, presets } from 'postcss-rule-unit-converter'

const result = await postcss([
  unitConverter({
    rules: composeRules(
      presets.rpxPresetGroup({
        ratio: 2,
        rootValue: 16,
        viewportWidth: 375,
        viewportHeight: 667,
      }),
      {
        from: 'em',
        to: 'rpx',
        factor: 32,
      },
    ),
  }),
]).process('.demo{font-size:32rpx;left:10vw}', { from: undefined })

内置的分组 preset:

  • presets.rpxPresetGroup()px/rem/vw/vh 归一成 rpx
  • presets.pxPresetGroup()rem/rpx/vw/vh 归一成 px
  • presets.viewportPresetGroup()px/rem/rpx 归一成单一目标轴的 vwvh
  • presets.webPresetGroup() 提供一组偏 Web 场景的 px/rem/vw/vh/rpx 常用规则

postcss-units-to-px 迁移

presets.unitsToPx() 支持和 postcss-units-to-px 同形状的 unitMap

import postcss from 'postcss'
import unitConverter, { presets } from 'postcss-rule-unit-converter'

const result = await postcss([
  unitConverter({
    propList: ['*'],
    rules: presets.unitsToPx({
      unitMap: {
        rem: 16,
        vw: false,
        foo: null,
      },
      transform(value, unit, context) {
        return unit === 'foo' && context.prop === 'margin' ? value * 10 : undefined
      },
    }),
  }),
]).process('.demo{font-size:1rem;width:1vw;margin:2foo}', { from: undefined })

对象形式的 unitMap 会覆盖并合并默认的 rem/em/vw/vh/vmin/vmax/rpx 映射。Map 和数组形式会保留用户传入顺序,并且不合并默认值。单个单位规则为 false 时跳过该单位;为 null 时走 transform(value, unit, context) 兜底。

更多示例

import postcss from 'postcss'
import unitConverter, { presets } from 'postcss-rule-unit-converter'

const result = await postcss([
  unitConverter({
    rules: [
      presets.rpxToPx(),
      presets.pxToRpx(),
      presets.rpxToRem({ rootValue: 16 }),
      presets.rpxToVw({ viewportWidth: 375 }),
      presets.rpxToVh({ viewportHeight: 667 }),
      presets.vwToPx({ viewportWidth: 375 }),
      presets.vhToPx({ viewportHeight: 667 }),
    ],
  }),
]).process('.demo{font-size:32rpx;width:10vw;height:10vh}', { from: undefined })

自定义 Preset

单条 preset,自带导出的类型:

import type { PresetFactory, RemBasedPresetOptions } from 'postcss-rule-unit-converter'
import postcss from 'postcss'
import unitConverter, {
  definePreset

} from 'postcss-rule-unit-converter'

const remToDp: PresetFactory<RemBasedPresetOptions> = definePreset((options = {}) => {
  const { rootValue = 16, minValue, to = 'dp' } = options
  return {
    from: 'rem',
    to,
    minValue,
    transform: (value, context) => {
      const resolvedRootValue = typeof rootValue === 'function'
        ? rootValue(context.input)
        : rootValue
      return value * resolvedRootValue
    },
  }
})

const result = await postcss([
  unitConverter({
    rules: [remToDp({ rootValue: 20 })],
  }),
]).process('.demo{font-size:1rem}', { from: undefined })

分组 preset,自带导出的类型:

import type { PresetGroupFactory, RemBasedPresetOptions } from 'postcss-rule-unit-converter'
import postcss from 'postcss'
import unitConverter, {
  definePresetGroup

} from 'postcss-rule-unit-converter'

type MyPresetOptions = RemBasedPresetOptions & {
  ratio?: number
}

const mobilePresetGroup: PresetGroupFactory<MyPresetOptions> = definePresetGroup((options = {}) => {
  const { rootValue = 16, ratio = 2 } = options
  return [
    {
      from: 'rem',
      to: 'rpx',
      transform: (value, context) => {
        const resolvedRootValue = typeof rootValue === 'function'
          ? rootValue(context.input)
          : rootValue
        return value * resolvedRootValue * ratio
      },
    },
    {
      from: 'px',
      to: 'rpx',
      factor: ratio,
    },
  ]
})

const result = await postcss([
  unitConverter({
    rules: mobilePresetGroup({ rootValue: 16, ratio: 2 }),
  }),
]).process('.demo{font-size:1rem;margin:16px}', { from: undefined })

自定义 transform 规则:

import postcss from 'postcss'
import unitConverter from 'postcss-rule-unit-converter'

const result = await postcss([
  unitConverter({
    rules: [
      {
        from: /^x$/,
        to: 'px',
        transform(value, context) {
          return context.prop === 'letter-spacing' ? value * 4 : value * 8
        },
      },
    ],
  }),
]).process('.demo{letter-spacing:2x;margin:2x}', { from: undefined })

使用建议

  • 想保留兜底声明时,用 replace: false
  • 想避免多条 preset 对同一源单位发生竞争时,用 propList 把适用范围收窄。
  • 项目里如果有一个主单位体系,优先使用 preset group。
  • 如果你要严格控制命中顺序,优先直接写显式规则数组。
  • 使用 presets.viewportPresetGroup() 时,建议显式指定 viewportUnit: 'vw'viewportUnit: 'vh'
  • 在业务里沉淀可复用 preset 时,优先使用 definePreset(...)definePresetGroup(...)
  • RuleContext.fromUnit 是用于规则匹配的源单位;rawUnit 保留原始大小写;rawValueNumber(...) 前的数字文本;match 是完整匹配片段。
  • 字符串单位 matcher 会归一化为小写。默认正则下 'px' 匹配小写 px;需要匹配 PX/Px 时使用 /^px$/i 或自定义 unitRegex
  • 默认正则会跳过字符串、url(...)var(...)。自定义 unitRegex 会完全替换默认正则;如果仍要跳过这些内容,需要在自定义正则里保留跳过分支。
  • 如果你想直接抄场景配置,优先看 cookbook。

Presets

自定义 preset 辅助类型:

  • definePreset()

  • definePresetGroup()

  • type PresetFactory<TOptions>

  • type PresetGroupFactory<TOptions>

  • presets.remToPx()

  • presets.remToRpx()

  • presets.remToRpxRatio()

  • presets.remToRpxByRatio()

  • presets.remToResponsivePixel()

  • presets.remToViewport()

  • presets.remToVw()

  • presets.remToVh()

  • presets.pxToRem()

  • presets.pxToViewport()

  • presets.pxToVw()

  • presets.pxToVh()

  • presets.pxToRpx()

  • presets.rpxToPx()

  • presets.rpxToRem()

  • presets.rpxToVw()

  • presets.rpxToVh()

  • presets.vwToPx()

  • presets.vhToPx()

  • presets.vwToRem()

  • presets.vhToRem()

  • presets.vwToRpx()

  • presets.vhToRpx()

  • presets.pxPresetGroup()

  • presets.rpxPresetGroup()

  • presets.viewportPresetGroup()

  • presets.webPresetGroup()

  • presets.unitsToPx()