Skip to content

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

参数

参数名类型必填说明
tokensTokenMap设计令牌映射对象
prefixstringCSS 变量前缀(如 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\"}"
}

输出格式对比

特性CSSSCSSLessJS/TSJSON
变量语法--color: value$color: value@color: valuecolor: 'value'"color": "value"
对象支持生成 CSS 类保持字符串保持字符串嵌套对象保持字符串
颜色格式8位 hex8位 hex8位 hex8位 hex 字符串8位 hex 字符串
类型安全是(配合 TS 类型)
导入方式@import@import@importimport读取文件
运行时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 模块是设计令牌系统的重要组成部分,确保设计规范能够无缝转换为各种技术栈可用的代码格式。