Tamagui 配置完全指南:从 createTamagui 到生产级设计系统
【免费下载链接】tamaguiStyle React fast with 100% parity on React Native, an optional UI kit, and optimizing compiler.项目地址: https://gitcode.com/GitHub_Trending/ta/tamagui
本文围绕 Tamagui 的配置体系展开,系统讲解createTamagui的完整配置结构、v5 预构建配置的选用策略、Tokens/Themes/Fonts/Media Queries/Shorthands 五大配置板块的写法与实战用法,并结合@tamagui/config、@tamagui/web与@tamagui/cli的源码实现说明底层解析机制。读完本文,你将能独立编写一份类型安全、可跨 Web 与 React Native 复用的 Tamagui 配置文件,并借助npx tamagui generate-prompt为项目生成可直接投喂给 AI 助手的配置快照。
createTamagui:一切配置的入口
Tamagui 的配置入口是createTamagui函数,它接收一个包含tokens、themes、fonts、media、shorthands、animations、settings等字段的配置对象,并返回一个带完整类型推断的配置实例:
import { createTamagui } from '@tamagui/core' const config = createTamagui({ tokens, themes, fonts, media, shorthands, animations, settings, }) export default config从 createTamagui 的源码实现 可以看到,这个函数并非简单地把对象存起来,而是做了多项预处理:
- Token 变量化与预解析:通过
createVariables(configIn.tokens || {})把 tokens 包装为运行时变量,并对每个分类同时注册$key与裸key两种查找形式(见tokensParsed/tokensMerged的双映射逻辑),这也是组件里padding="$4"与padding="$space.4"两种写法都能生效的底层原因。 - 配置合并与复用:如果检测到已存在配置(例如 Vite SSR 场景下存在多份 Tamagui 副本),会先做
{ ...existingConfig, ...configIn }合并再继续初始化,避免重复初始化导致的状态错乱。 - 环境接线:最终通过
setConfig(config)与configureMedia(config)把配置写入全局,并将 media query 解析为可用的媒体查询上下文。
需要留意的是,createTamagui的类型定义(InferTamaguiConfig<Conf>)会让你的编辑器根据实际传入的 tokens、字体名等自动推断出$color.blue、$font.body这类可用的 token 值,实现开箱即用的类型提示。
使用预构建配置:v5 家族的四种选择
大多数项目不需要从零手写所有配置。@tamagui/config包提供了开箱即用的 v5 配置族,v5-base.ts 中导出的defaultConfig已经聚合了 themes、media、shorthands、tokens、fonts、selectionStyles 与 settings,你只需要按动画方案选择对应的入口:
// v5 with CSS animations (web) import { config } from '@tamagui/config/v5-css' // v5 with Motion animations (cross-platform) import { config } from '@tamagui/config/v5-motion' // v5 with Reanimated (best native performance) import { config } from '@tamagui/config/v5-reanimated' // v5 base (no animations, add your own) import { defaultConfig } from '@tamagui/config/v5' import { animations } from '@tamagui/config/v5-css' export default createTamagui({ ...defaultConfig, animations, })四种动画方案的底层差异直接体现在各自源码中:
| 入口 | 动画引擎 | 适用场景 |
|---|---|---|
@tamagui/config/v5-css | CSS 过渡 / cubic-bezier 曲线 | Web 端,动画在样式层面完成,零 JS 运行时开销 |
@tamagui/config/v5-motion | Motion(跨平台 spring/timing) | 需要 Web 与 Native 动画行为一致的跨平台项目 |
@tamagui/config/v5-reanimated | Reanimated(spring/timing) | Native 端追求动画性能的项目 |
@tamagui/config/v5 | 无动画 | 只想要基础配置、自备动画方案 |
以 v5-css.ts 为例,CSS 方案预置了quick、bouncy、lazy、medium、slow等一套命名完整的时长动画,例如quick: 150ms ease-out、superBouncy: 300ms cubic-bezier(0.175, 0.885, 0.32, 1.5);而 v5-motion.ts 与 v5-reanimated.ts 则把这些名字映射为 spring 物理参数(damping、mass、stiffness),例如 Reanimated 方案中quick对应damping: 25, mass: 1, stiffness: 550。因此同一套animation="bouncy"写法在不同平台入口下会自动获得语义一致的动画体验。
另外,v5.ts 会从@tamagui/themes/v5重导出主题与 tokens,并组合 v5-base;如果需要旧版兼容,仓库还保留了@tamagui/config/v3、@tamagui/config/v4等历史入口(见 code/core/config 根目录的v3.cjs、v4.d.ts等文件)。
Tokens:设计系统的原子值
Tokens 是设计系统中可以被$前缀引用的基础值,按分类组织。文档给出了一个完整的最小示例:
tokens: { color: { white: '#fff', black: '#000', blue: '#0066cc', }, space: { 0: 0, 1: 4, 2: 8, 3: 12, 4: 16, 5: 20, true: 16, // default when using boolean }, size: { 0: 0, 1: 20, 2: 24, 3: 28, 4: 32, true: 32, }, radius: { 0: 0, 1: 4, 2: 8, 3: 12, 4: 16, true: 8, }, zIndex: { 0: 0, 1: 100, 2: 200, }, }使用方式:
<View padding="$4" borderRadius="$2" />几个关键约定:
$前缀:padding="$4"等价于padding="$space.4"。createTamagui在初始化时会为每个 token 分类注册$key形式的快捷查找(见上文源码分析),这正是裸数字引用得以工作的原因。true键:各分类中的true是布尔简写的默认值——当你写padding而不给具体值时,会取space.true(文档示例中为16)。这也是size.true、radius.true存在的意义。- 分类语义:
space控制间距(4px 步进)、size控制尺寸(20px 起跳)、radius控制圆角、zIndex控制层级,分类名本身也是命名空间的一部分。
v5 预构建配置使用了来自@tamagui/themes/v5的更完整 tokens 集,defaultConfig已为你配好全套色彩与尺寸变量,可以直接通过$color.blue10、$size.lg这类语义名引用。
Themes:语义化配色方案
Themes 用语义化名称定义颜色方案,而非直接写死颜色值:
themes: { light: { background: '#fff', color: '#000', color1: '#f8f8f8', color2: '#f0f0f0', // ... color3-12 borderColor: '#e0e0e0', }, dark: { background: '#000', color: '#fff', color1: '#111', color2: '#222', // ... color3-12 borderColor: '#333', }, // sub-themes combine with parent: dark_blue, light_blue blue: { background: '#0066cc', color: '#fff', }, }使用方式:
<Theme name="dark"> <View backgroundColor="$background" /> </Theme>- 子主题组合:如注释所示,
blue作为子主题会与父主题自动组合出dark_blue、light_blue等变体,无需逐一声明。 - 命名约定:
color1~color12是从浅到深的色阶梯度,配合borderColor、background、color等语义键,组件只需引用语义名即可自动适配明暗两套皮肤。 - 主题切换:
settings.shouldAddPrefersColorThemes开启后,Web 端会自动生成跟随prefers-color-scheme的浅色/深色 CSS,实现系统级自动换肤。
v5 主题体系由@tamagui/theme-builder与@tamagui/create-theme支撑(v5-base.ts中重导出了createThemes、createV5Theme、defaultDarkPalette等工具),这意味着你可以基于调色板程序化生成整套主题,而不是手写每一个颜色键。
Fonts:字体体系与阶梯尺寸
字体通过createFont创建,本质是一个带family、size、lineHeight、weight、letterSpacing五个维度的阶梯对象:
import { createFont } from '@tamagui/core' const bodyFont = createFont({ family: 'Inter, system-ui, sans-serif', size: { 1: 12, 2: 14, 3: 16, 4: 18, 5: 20, 6: 24, }, lineHeight: { 1: 17, 2: 20, 3: 22, 4: 24, 5: 26, 6: 30, }, weight: { 4: '400', 5: '500', 6: '600', 7: '700', }, letterSpacing: { 4: 0, 5: -0.2, 6: -0.4, }, }) // in config fonts: { body: bodyFont, heading: headingFont, mono: monoFont, }使用方式:
<Text fontFamily="$body" fontSize="$4" />- 阶梯映射:
size与lineHeight、weight、letterSpacing通过同一个数字档位关联——fontSize="$4"会同时取到第 4 档的 size、lineHeight、weight 与 letterSpacing,无需逐一指定。 true档:与 tokens 类似,数字阶梯也可提供true档作为默认值。- 字体命名空间:配置中的
fonts.body、fonts.heading直接决定了$body、$heading这类$font.xxx引用。
@tamagui/config内部通过createSystemFont(见 v5-fonts.ts)按平台生成系统字体:Web 端使用-apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto...栈,Native 端则使用System;同时按平台区分字号——Native 端对齐 iOS HIG(body 17pt、subheadline 15pt、caption 12pt),Web 端按 12px 起步的网页习惯;行高在 Native 端按size + 5,Web 端按 150% 起并向大字号渐缩至约 142%。如果你希望完全替换字体,只需基于createFont覆盖fonts.body等键即可。
Media Queries:响应式与特性查询
Media 配置同时支持最大/最小宽度查询和特性查询,并且每个键都可以通过$前缀作用在任意组件上:
media: { xs: { maxWidth: 660 }, sm: { maxWidth: 800 }, md: { maxWidth: 1020 }, lg: { maxWidth: 1280 }, xl: { maxWidth: 1420 }, // "greater than" queries gtXs: { minWidth: 661 }, gtSm: { minWidth: 801 }, gtMd: { minWidth: 1021 }, gtLg: { minWidth: 1281 }, // feature queries pointerFine: { pointer: 'fine' }, }使用方式:
<View padding="$4" $gtSm={{ padding: '$6' }} $gtMd={{ padding: '$8' }} />$条件前缀:$gtSm、$md等作为 props 直接施加于组件,命中的媒体条件下会覆盖基础样式。媒体键的命名、顺序与优先级都基于你定义的 media 对象。- 特性查询:
{ pointer: 'fine' }、{ hover: 'hover' }这类键可区分指针设备能力,是触屏与桌面交互差异处理的利器。 - SSR 默认值:
settings.mediaQueryDefaultActive可声明服务端渲染时默认视为命中的查询(例如gtSm: true, gtMd: true),避免首屏与客户端水合时的闪烁差异。
v5 预构建配置在 v5-media.ts 中定义了更细化的断点体系:xxxs/xxs/xs/sm/md/lg/xl/xxl一组minWidth查询,配套max-xxl~max-100一组maxWidth查询,外加max-height-*、height-*高度查询与touchable、hoverable特性查询。其中两个值得注意的实现细节:
- 防重叠偏移:
mediaQueryForceNonOverlap在 Native 目标下为 1、Web 下为 0.02,用于微调 max 类断点(如breakpoints.xxl - 0.02),避免相邻 max/min 查询在同一像素重叠。 - 对象顺序即优先级:源码注释明确指出"越靠后定义、CSS 优先级越高",因此高度查询被刻意放在宽度查询之后,
non-max查询被放在max查询之后,保证同时命中时行为可预期。
Shorthands:属性缩写映射
Shorthands 把短属性名映射为完整样式属性,是减少样板代码的高频手段:
shorthands: { p: 'padding', m: 'margin', bg: 'backgroundColor', w: 'width', h: 'height', px: 'paddingHorizontal', py: 'paddingVertical', mx: 'marginHorizontal', my: 'marginVertical', br: 'borderRadius', } as const使用方式:
<View p="$4" bg="$background" br="$2" />- 类型约束:
as const保证键值映射被 TypeScript 精确推断,从而在组件上使用p、bg时获得与完整属性一致的校验。 - 与 settings 联动:
settings.onlyAllowShorthands为true时只允许缩写写法(v5 默认即如此,见 v5-base.ts);为false时缩写与全名可混用。 - 冲突规避:若某个组件恰好有同名自定义 prop(如
bg),可通过设置关闭缩写或将冲突项从映射中移除。
Settings:全局行为开关
Settings 控制 Tamagui 的运行时行为与样式策略:
settings: { defaultFont: 'body', shouldAddPrefersColorThemes: true, // auto light/dark CSS allowedStyleValues: 'somewhat-strict-web', autocompleteSpecificTokens: 'except-special', onlyAllowShorthands: false, // allow both short and long names mediaQueryDefaultActive: { // SSR: assume these queries are true initially gtSm: true, gtMd: true, }, }各字段说明:
defaultFont:未显式指定fontFamily时使用的字体键,默认body。shouldAddPrefersColorThemes:为true时 Web 端自动注入prefers-color-scheme的浅/深色 CSS。allowedStyleValues:样式值校验的严格程度,somewhat-strict-web在 Web 端对未知值给出警告而非阻断。autocompleteSpecificTokens:控制哪些 token 进入自动补全提示,except-special会排除如true等特殊档位。onlyAllowShorthands:是否只允许缩写属性写法。mediaQueryDefaultActive:SSR/首屏时默认视为命中的媒体查询集合。
v5 预构建配置还额外启用了fastSchemeChange: true(快速切换明暗主题)与addThemeClassName: 'html'(把主题类名挂在<html>上以支持 CSS 主题方案),并设置styleCompat: 'web'让样式语义向 Web 对齐——这些默认值全部定义在 v5-base.ts 的settings对象中。
TypeScript 集成:把配置注入类型系统
要让全项目享受到 token 与主题的类型提示,需要声明模块扩充:
// tamagui.config.ts const config = createTamagui({...}) export type Conf = typeof config declare module 'tamagui' { interface TamaguiCustomConfig extends Conf {} } export default configtypeof config会捕获createTamagui推断出的完整配置形状(含 tokens 分类、字体键、媒体键)。- 通过
declare module 'tamagui'扩充TamaguiCustomConfig接口后,<View padding="$4">、<Text fontSize="$4">、<View $gtSm={...}>等写法的取值都会在你的 tokens/media 基础上校验与提示。 - 仓库中的示例应用(如 sandbox/config、kitchen-sink-shared/src)均遵循此模式组织配置文件,可作为参考。
Provider 接入:让配置生效
配置必须在应用根部通过TamaguiProvider注入:
import { TamaguiProvider } from 'tamagui' import config from './tamagui.config' export default function App() { return ( <TamaguiProvider config={config}> {/* app content */} </TamaguiProvider> ) }- Provider 接收上一步导出的
config,将 tokens、themes、media 等上下文传递给整棵组件树。 - 在 Next.js / Remix 等框架中,Provider 通常放在根布局或
_app中,确保所有页面共享同一套配置。 - 如果同时使用 Tamagui 的编译优化(
@tamagui/static/ Babel 插件),Provider 与配置模块还需要能被编译管线正确识别与预提取。
生成项目配置快照:npx tamagui generate-prompt
Tamagui CLI 提供了一条面向 AI 辅助开发与文档化的命令,可把当前项目的真实配置导出为 Markdown:
npx tamagui generate-prompt它会生成tamagui-prompt.md,包含你项目中实际生效的tokens、themes、media queries 与组件清单——而非通用示例。
从 generate-prompt 的实现 可以看到其执行链路:
- 设置
TAMAGUI_KEEP_THEMES = '1'后调用@tamagui/static的loadTamagui,按 web 平台重新加载配置; - 读取编译产物
.tamagui/tamagui.config.json(该文件需先由tamagui generate生成,若缺失会抛出明确错误提示); - 将 JSON 配置序列化为 Markdown 并写入当前工作目录的
tamagui-prompt.md(可通过--output参数自定义路径)。
这意味着该命令是"编译期真实配置"的导出器:它会反映经过 tokens 解析、主题生成后的最终配置形态,适合直接粘贴给 AI 助手做上下文,也适合在文档评审时快速核对项目当前的设计系统快照。仓库根目录中的 tamagui.dev/tamagui-prompt.md 即是该机制的真实产物示例。
小结:一套配置,多端生效
Tamagui 的配置体系可以概括为一条主线:createTamagui聚合 tokens、themes、fonts、media、shorthands、animations、settings 七类配置,在初始化阶段完成 token 变量化、媒体查询解析与类型推断,再由TamaguiProvider注入应用;@tamagui/config的 v5 家族提供了开箱即用的默认配置与四种动画方案,generate-prompt则把这份配置导出为可共享、可投喂给 AI 的 Markdown 快照。结合 createTamagui 源码、v5 配置源码 与 CLI 实现,你可以在此基础上按需裁剪:替换字体、扩展断点、定制调色板,甚至基于theme-builder程序化生成整套主题,让同一份配置在 Web 与 React Native 两端保持一致的设计语言。
【免费下载链接】tamaguiStyle React fast with 100% parity on React Native, an optional UI kit, and optimizing compiler.项目地址: https://gitcode.com/GitHub_Trending/ta/tamagui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考