跳到主要内容

运行时 API

@weapp-tailwindcss/runtime 是所有运行时包的公共底座,统一提供 escape/unescape、clsx 封装、weappTwIgnore 以及 createRuntimeFactory@weapp-tailwindcss/mergemerge-v3cvavariants 都是基于它实现的。

安装

pnpm add @weapp-tailwindcss/merge

如果项目仍在使用 Tailwind CSS v3,请改用 @weapp-tailwindcss/merge-v3;而 @weapp-tailwindcss/runtime 在大部分场景下会作为间接依赖被自动安装。

Runtime 基本面

import {
clsx,
weappTwIgnore,
resolveTransformers,
createRuntimeFactory,
} from '@weapp-tailwindcss/runtime'
  • clsx / ClassValue:统一的类名聚合工具,避免各包重复安装 clsx
  • weappTwIgnoreString.raw 的别名,用于跳过 weapp 转义
  • resolveTransformers(createOptions):返回 { escape, unescape }
  • createRuntimeFactory(factoryOptions):将 tailwind-mergetailwind-variants 等库注入 weapp 运行时

merge 运行时的标准导出

所有 API 都与 tailwind-merge 原版保持一致,只是在调用前后包裹了转义逻辑。你可以继续使用熟悉的导入路径:

import {
twMerge,
twJoin,
createTailwindMerge,
extendTailwindMerge,
getDefaultConfig,
mergeConfigs,
tailwindMergeVersion,
weappTwIgnore,
create,
} from '@weapp-tailwindcss/merge'
  • @weapp-tailwindcss/merge 适配 tailwindcss@4
  • @weapp-tailwindcss/merge-v3 适配 tailwindcss@3

两个包内部均依赖 @weapp-tailwindcss/runtime,API 完全一致。

twMerge(...classValues)

合并 Tailwind 工具类并移除冲突项,返回一个经过小程序转义的字符串。支持布尔值、数字、数组、嵌套数组等所有 tailwind-merge 支持的参数类型。

twMerge('px-2 py-1', ['px-6', { 'py-5': shouldExpand }])
// => 'px-6 py-5'

twMerge('text-[#ececec]', flag && 'text-[#ECECEC]')
// => 'text-_b_hECECEC_B'

常见问题

  • 如果输入已经是转义过的占位符(例如 text-_b_hececec_B),运行时会先调用 unescape 还原,再进行合并,因此不会出现重复。
  • 返回结果永远是字符串;若想在 Web 端保持原样,需要使用下文的 create 禁用转义。

twJoin(...classValues)

单纯把类名拼接成一个字符串,不做冲突判断,但仍会执行「先 unescape、后 escape」的流程,保证多端结果一致。适合用于低成本地去除 undefined / false

twJoin('text-[#ececec]', condition && 'bg-[#010101]')
// => 'text-_b_hececec_B bg-_b_h010101_B'

createTailwindMerge(config)

与原版一致,可以基于自定义配置创建一个新的 twMerge 实例。区别在于返回值会自动带上小程序转义。

const mergeCard = createTailwindMerge({
classGroups: {
card: ['card-default', 'card-primary'],
},
})

mergeCard('card-default card-primary') // => 'card-primary'

同一个实例在调用过程中仍然执行转义,因此你可以安全地混用转义前后的字符串。

extendTailwindMerge(config)

基于默认配置扩展新的合并规则,返回一个新的 twMerge 运行时。

const mergeWithCustomSpacing = extendTailwindMerge({
classGroups: {
spacing: ['gap-safe', 'gap-huge'],
},
})

mergeWithCustomSpacing('gap-huge gap-safe') // => 'gap-safe'

getDefaultConfig() 与 mergeConfigs(a, b)

两者直接透传自 tailwind-merge

  • getDefaultConfig() 返回内部使用的原始配置对象;
  • mergeConfigs(a, b) 用于把两个配置合并成一个新的配置,常见于库内部复用。

tailwindMergeVersion

表示当前入口绑定的 tailwind-merge 主版本:

  • 2 ➜ 运行时基于 tailwind-merge@2,适配 tailwindcss@3
  • 3 ➜ 运行时基于 tailwind-merge@3,适配 tailwindcss@4

该值可用于调试或在运行时判断最终行为。

weappTwIgnore

模板字符串标签函数,本质是 String.raw。与 weapp-tailwindcssignoreTaggedTemplateExpressionIdentifiers 配置联动,用来标记「不要转义」的代码片段。

import { weappTwIgnore } from '@weapp-tailwindcss/merge'

const raw = weappTwIgnore`
bg-[#123456]
before:content-['>']
`

当小程序端确实需要原始类名(例如传递给第三方库)时,可借助该标签避免被编译期改写。

create(options?)

create 会根据传入的 options 返回一组隔离的运行时函数(twMergetwJoincreateTailwindMergeextendTailwindMerge),用于控制转义行为:

const { twMerge: mergeForWeb } = create({ escape: false, unescape: false })
const { twMerge: mergeForMiniProgram } = create()

CreateOptions

选项类型默认值说明
escapefalse | EscapeOptions{ map: 默认映射 }控制输出时是否转义;传入对象可自定义映射表。
unescapefalse | UnescapeOptions{ map: 默认映射 }控制在合并前是否还原占位符。
  • 传入 false 会彻底关闭对应阶段;
  • escape/unescape 同时提供自定义 map 时,运行时会自动与默认映射 MappingChars2String 合并,确保和编译期保持一致;
  • 该工厂返回的实例不会影响默认导出的全局实例,可在多端方案里自由组合。
  • EscapeOptions/UnescapeOptions 类型来自 @weapp-core/escape 包,与编译期所使用的转义逻辑保持一致。
import { create } from '@weapp-tailwindcss/merge'

const custom = create({
escape: {
map: {
'#': '__hash__',
},
},
unescape: {
map: {
'#': '__hash__',
},
},
})

custom.twMerge('text-[#ececec]') // => 'text-_b__hash__ececec_B'
custom.twMerge('text-_b__hash__ececec_B') // => 'text-_b__hash__ececec_B'

基于 runtime 的其他包

  • @weapp-tailwindcss/cva:封装 class-variance-authority,详见 cva 支持
  • @weapp-tailwindcss/variants:封装 tailwind-variants,详见 variants 支持
  • @weapp-tailwindcss/merge-v3:面向 tailwindcss@3 的长期支持分支

它们全部依赖 @weapp-tailwindcss/runtime,因此可以共享 escape 配置、weappTwIgnore 以及 clsx