generateVariables
将解析后的设计令牌转换为多种代码格式(CSS、SCSS、Less、JS、TS、JSON)的工具函数集合。所有函数均为纯函数,支持 8 位十六进制颜色格式化。
模块概述
generateVariables 模块提供一组纯函数,用于将 TokenMap(从 Excel 解析的设计令牌)转换为不同技术栈可用的格式:
- CSS 变量:生成
:root { --color: #RRGGBBAA; }格式 - SCSS/Less 变量:生成
$color: #RRGGBBAA;格式 - JavaScript 对象:生成
export const tokens = { color: '#RRGGBBAA' }格式 - TypeScript 类型:生成
export interface Tokens { color: string }格式 - JSON 数据:生成格式化的 JSON 对象
核心特性
- 纯函数:无副作用,相同输入产生相同输出
- 8 位十六进制:自动将 RGBA 转换为
#RRGGBBAA格式 - 类型安全:完整的 TypeScript 支持
- 对象支持:自动处理复合令牌(如文字样式对象)
- 前缀支持:可自定义变量/属性名前缀
函数列表
| 函数名 | 描述 | 输入 | 输出 |
|---|---|---|---|
| generateCSSVariables | 生成 CSS 自定义属性和类 | TokenMap, prefix? | CSS 字符串 |
| generateSCSSVariables | 生成 SCSS 变量 | TokenMap, prefix? | SCSS 字符串 |
| generateLessVariables | 生成 Less 变量 | TokenMap, prefix? | Less 字符串 |
| generateJSVariables | 生成 JS 对象 | TokenMap, exportName? | JS 代码字符串 |
| generateTSTypes | 生成 TS 类型定义 | TokenMap, typeName? | TS 类型字符串 |
| generateJSONVariables | 生成 JSON 数据 | TokenMap, indent? | JSON 字符串 |
函数详情
generateCSSVariables
typescript
/**
* 生成CSS变量格式的设计令牌
*
* 将设计令牌转换为CSS自定义属性(变量),支持对象类型令牌的自动转换为CSS类。
* 对于颜色值,自动转换为8位十六进制格式(包含alpha通道)。
*
* @param tokens - 解析出的设计令牌映射
* @param prefix - CSS变量前缀,默认为空字符串
* @returns CSS变量和类的字符串内容
*/
export function generateCSSVariables(tokens: TokenMap, prefix: string = ''): string参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
tokens | TokenMap | 是 | 设计令牌映射对象 |
prefix | string | 否 | CSS 变量前缀(如 dt 生成 --dt-color) |
返回值:CSS 字符串,包含 :root 变量和可能的 CSS 类
示例
typescript
import { generateCSSVariables } from 'zcw-shared/functions/design-tokens/generateVariables'
const tokens = {
'brand-color': 'rgba(0, 119, 255, 0.8)', // 自动转换为 #0077FFCC
'radius-small': '4px',
'text-body': JSON.stringify({
fontWeight: '400',
fontSize: 'var(--font-size-md)',
lineHeight: '1.5'
})
}
const css = generateCSSVariables(tokens, 'dt')
// 输出:
/*
:root {
--dt-brand-color: #0077FFCC;
--dt-radius-small: 4px;
}
.text-body {
font-weight: 400;
font-size: var(--font-size-md);
line-height: 1.5;
}
*/generateSCSSVariables
typescript
/**
* 生成SCSS变量格式的设计令牌
*
* 将设计令牌转换为SCSS变量,支持8位十六进制颜色格式。
*
* @param tokens - 解析出的设计令牌映射
* @param prefix - SCSS变量前缀,默认为空字符串
* @returns SCSS变量字符串内容
*/
export function generateSCSSVariables(tokens: TokenMap, prefix: string = ''): string示例
scss
// 生成的 SCSS
$dt-brand-color: #0077FFCC;
$dt-radius-small: 4px;
// 使用
.button {
background: $dt-brand-color;
border-radius: $dt-radius-small;
}generateLessVariables
typescript
/**
* 生成Less变量格式的设计令牌
*
* 将设计令牌转换为Less变量,支持8位十六进制颜色格式。
*
* @param tokens - 解析出的设计令牌映射
* @param prefix - Less变量前缀,默认为空字符串
* @returns Less变量字符串内容
*/
export function generateLessVariables(tokens: TokenMap, prefix: string = ''): string示例
less
// 生成的 Less
@dt-brand-color: #0077FFCC;
@dt-radius-small: 4px;
// 使用
.button {
background: @dt-brand-color;
border-radius: @dt-radius-small;
}generateJSVariables
typescript
/**
* 生成JavaScript/TypeScript对象格式的设计令牌
*
* 将设计令牌转换为JavaScript/TypeScript对象,支持对象类型令牌的嵌套结构和8位十六进制颜色格式。
*
* @param tokens - 解析出的设计令牌映射
* @param exportName - 导出的对象名称,默认为 'designTokens'
* @returns JavaScript/TypeScript代码字符串
*/
export function generateJSVariables(tokens: TokenMap, exportName: string = 'designTokens'): string示例
typescript
// 生成的 JS/TS
export const designTokens = {
brandColor: '#0077FFCC',
radiusSmall: '4px',
textBody: {
fontWeight: '400',
fontSize: 'var(--font-size-md)',
lineHeight: '1.5'
}
}
// 使用
import { designTokens } from './tokens'
const buttonStyle = {
backgroundColor: designTokens.brandColor,
borderRadius: designTokens.radiusSmall,
...designTokens.textBody
}generateTSTypes
typescript
/**
* 生成TypeScript类型定义
*
* 为设计令牌生成TypeScript接口定义,所有值类型为string。
*
* @param tokens - 解析出的设计令牌映射
* @param typeName - 类型名称,默认为 'DesignTokens'
* @returns TypeScript类型定义字符串
*/
export function generateTSTypes(tokens: TokenMap, typeName: string = 'DesignTokens'): string示例
typescript
// 生成的 TS 类型
export interface DesignTokens {
brandColor: string
radiusSmall: string
textBody: string // JSON 字符串类型
}
// 使用
import type { DesignTokens } from './tokens'
const styles: DesignTokens = {
brandColor: designTokens.brandColor,
radiusSmall: designTokens.radiusSmall,
textBody: JSON.stringify(designTokens.textBody)
}generateJSONVariables
typescript
/**
* 生成JSON格式的设计令牌
*
* 将设计令牌转换为格式化的JSON对象,支持8位十六进制颜色格式。
*
* @param tokens - 解析出的设计令牌映射
* @param indent - 缩进空格数,默认为2
* @returns JSON字符串
*/
export function generateJSONVariables(tokens: TokenMap, indent: number = 2): string示例
json
// 生成的 JSON
{
"brand-color": "#0077FFCC",
"radius-small": "4px",
"text-body": "{\"fontWeight\":\"400\",\"fontSize\":\"var(--font-size-md)\",\"lineHeight\":\"1.5\"}"
}输出格式对比
| 特性 | CSS | SCSS | Less | JS/TS | JSON |
|---|---|---|---|---|---|
| 变量语法 | --color: value | $color: value | @color: value | color: 'value' | "color": "value" |
| 对象支持 | 生成 CSS 类 | 保持字符串 | 保持字符串 | 嵌套对象 | 保持字符串 |
| 颜色格式 | 8位 hex | 8位 hex | 8位 hex | 8位 hex 字符串 | 8位 hex 字符串 |
| 类型安全 | 否 | 否 | 否 | 是(配合 TS 类型) | 否 |
| 导入方式 | @import | @import | @import | import | 读取文件 |
| 运行时 | CSS 引擎 | Sass 编译 | Less 编译 | JavaScript 运行时 | 任意 |
使用示例
完整构建流程
typescript
import {
buildTokens,
generateCSSVariables,
generateJSVariables,
generateTSTypes
} from 'zcw-shared/functions/design-tokens'
// 1. 从 Excel 构建令牌
const result = buildTokens(config, XLSX, deps, logger)
const tokens = result.files.find(f => f.format === 'JSON') // 或者直接从内存获取
// 2. 手动生成特定格式(可选)
const cssContent = generateCSSVariables(tokensMap, 'dt')
const jsContent = generateJSVariables(tokensMap, 'designTokens')
const tsTypes = generateTSTypes(tokensMap, 'DesignTokens')
// 3. 写入文件
fs.writeFileSync('./custom-tokens.css', cssContent)
fs.writeFileSync('./design-tokens.js', jsContent)
fs.writeFileSync('./design-tokens.d.ts', tsTypes)动态令牌生成
typescript
import {
generateCSSVariables,
generateSCSSVariables,
generateJSVariables
} from 'zcw-shared/functions/design-tokens'
// 运行时动态生成
const runtimeTokens = {
'primary-color': '#0077FF',
'success-color': 'rgba(16, 185, 129, 0.8)', // 自动转为 #10B981CC
'theme-dark': JSON.stringify({
background: '#1f2937',
textColor: '#f9fafb'
})
}
// 生成不同格式
const css = generateCSSVariables(runtimeTokens, 'rt')
const scss = generateSCSSVariables(runtimeTokens, 'rt')
const js = generateJSVariables(runtimeTokens, 'runtimeTokens')
console.log('CSS:', css)
console.log('SCSS:', scss)
console.log('JS:', js)前缀使用
typescript
const tokens = { 'brand-color': '#0077FF', 'text-primary': '#1f2937' }
// 无前缀
const cssNoPrefix = generateCSSVariables(tokens)
// :root {
// --brand-color: #0077FF;
// --text-primary: #1F2937FF;
// }
// 有前缀
const cssWithPrefix = generateCSSVariables(tokens, 'dt')
// :root {
// --dt-brand-color: #0077FF;
// --dt-text-primary: #1F2937FF;
// }最佳实践
1. 生产环境配置
typescript
// 推荐的生成配置
const productionTokens = generateTokensFromExcel('./design-tokens.xlsx')
// 生成核心格式
const css = generateCSSVariables(productionTokens, 'design')
const scss = generateSCSSVariables(productionTokens, 'design')
const types = generateTSTypes(productionTokens, 'DesignSystemTokens')
// 单独导出到不同目录
writeFile('./dist/css/design-tokens.css', css)
writeFile('./src/styles/_design-tokens.scss', scss)
writeFile('./src/types/design-tokens.d.ts', types)2. 颜色格式验证
typescript
import { generateCSSVariables } from 'zcw-shared/functions/design-tokens/generateVariables'
// 验证生成的颜色格式
const css = generateCSSVariables(tokens)
const colorVars = css.match(/--\w+:\s*#([0-9A-Fa-f]{8})/g)
colorVars?.forEach((varDecl) => {
const hex = varDecl.match(/[0-9A-Fa-f]{8}/)?.[0]
if (hex && hex.length === 8) {
console.log('✅ 8位 hex 格式:', hex)
} else {
console.warn('⚠️ 颜色格式异常:', varDecl)
}
})3. 对象令牌处理
typescript
// 复合令牌(如文字样式)
const textTokens = {
'heading-1': JSON.stringify({
fontSize: 'var(--font-size-xl)',
fontWeight: '700',
lineHeight: '1.2'
}),
'body-text': JSON.stringify({
fontSize: 'var(--font-size-base)',
fontWeight: '400',
lineHeight: '1.5'
})
}
// JS 对象会自动解析
const jsCode = generateJSVariables(textTokens)
// export const designTokens = {
// heading1: {
// fontSize: "var(--font-size-xl)",
// fontWeight: "700",
// lineHeight: "1.2"
// },
// bodyText: {
// fontSize: "var(--font-size-base)",
// fontWeight: "400",
// lineHeight: "1.5"
// }
// }
// CSS 会生成类
const cssCode = generateCSSVariables(textTokens)
// .heading-1 {
// font-size: var(--font-size-xl);
// font-weight: 700;
// line-height: 1.2;
// }4. 性能优化
typescript
// 缓存生成的令牌
const tokenCache = new Map<string, string>()
function generateWithCache(
tokens: TokenMap,
format: 'css' | 'scss' | 'js',
prefix?: string
): string {
const cacheKey = `${format}-${JSON.stringify(tokens)}-${prefix || ''}`
if (tokenCache.has(cacheKey)) {
return tokenCache.get(cacheKey)!
}
let result: string
switch (format) {
case 'css':
result = generateCSSVariables(tokens, prefix)
break
case 'scss':
result = generateSCSSVariables(tokens, prefix)
break
case 'js':
result = generateJSVariables(tokens)
break
}
tokenCache.set(cacheKey, result)
return result
}集成示例
在构建脚本中使用
typescript
// build-tokens.js
import { buildTokens } from 'zcw-shared/functions/design-tokens/buildTokens'
import { generateCSSVariables, generateJSVariables } from 'zcw-shared/functions/design-tokens/generateVariables'
async function build() {
// 1. 构建所有格式
const result = await buildTokens(config, XLSX, deps)
// 2. 额外生成自定义格式
const customTokens = await parseCustomTokens() // 自定义解析逻辑
const customCSS = generateCSSVariables(customTokens, 'custom')
const customJS = generateJSVariables(customTokens, 'customTokens')
// 3. 写入额外文件
fs.writeFileSync('./dist/custom-tokens.css', customCSS)
fs.writeFileSync('./src/custom-tokens.js', customJS)
console.log('✅ 构建完成,包括自定义令牌')
}
build()与设计系统集成
typescript
// design-system/tokens.ts
import {
generateTSTypes,
generateJSVariables
} from 'zcw-shared/functions/design-tokens/generateVariables'
import type { DesignTokens } from './generated-tokens'
// 从构建过程中获取令牌
const rawTokens = loadDesignTokensFromBuild()
// 生成类型和运行时对象
export const DesignTokenTypes = generateTSTypes(rawTokens, 'DesignTokens')
export const designTokens = generateJSVariables(rawTokens, 'designTokens')
// 类型安全的访问器
export function getToken<K extends keyof DesignTokens>(key: K): DesignTokens[K] {
return designTokens[key]
}
// 使用示例
const primaryColor = getToken('primaryColor') // 类型安全!
const buttonStyle = {
backgroundColor: getToken('primaryColor'),
borderRadius: getToken('borderRadiusSm')
}generateVariables 模块是设计令牌系统的重要组成部分,确保设计规范能够无缝转换为各种技术栈可用的代码格式。