更新记录
1.0.0(2026-01-08) 下载此版本
平台兼容性
uni-app x(4.81)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | √ | × |
kux-vite-unocss
一个专为 uni-app x 项目设计的 UnoCSS Vite 插件,支持自动生成、转换和优化 UnoCSS 样式,确保在多端环境中的一致性和兼容性。
✨ 核心特性
- 🚀 自动扫描:自动扫描项目中的
.uvue文件,提取 UnoCSS 类名 - 🔧 智能转换:将现代 CSS 格式转换为 uni-app x 兼容格式
- ⚡ 性能优化:内置文件哈希缓存,支持增量构建和热更新
- 🎨 完整支持:兼容 UnoCSS 所有预设、自定义规则
- ⚠️ Attributify 限制:由于 uni-app x 框架限制,当前不支持 Attributify 模式
- 📦 自动输出:生成优化后的 CSS 文件到指定目录
- 🔍 详细日志:可选的详细日志输出,便于调试和问题排查
- 🔄 单位转换:自动转换 rem/em/vw/vh/vmin/vmax 等单位为 px/rpx
- 🎯 颜色格式转换:支持现代 RGB/HSL 格式转换为兼容格式
- ⚙️ 自定义配置:完全支持 UnoCSS 原生配置和扩展
📦 安装
插件市场:kux-vite-unocss
🚀 快速开始
1. 配置 Vite
在你的 vite.config.ts 文件中添加插件:
import { defineConfig } from 'vite'
import unocssForUniAppX from './uni_modules/kux-vite-unocss'
export default defineConfig({
plugins: [
unocssForUniAppX({
// 配置选项(可选)
outputDir: 'styles/css',
filename: 'uno.css',
watch: true,
cache: true,
cacheDir: ".hbuilderx/.cache/unocss-uni",
exclude: ["uni_modules/**", "components/**"],
})
]
})
2. 在页面中使用
在 .uvue 文件中使用 UnoCSS 类名和主题变量:
<template>
<view class="p-4 bg-white rounded-lg">
<text class="text-xl font-bold text-gray-800">Hello UnoCSS</text>
<view class="mt-4 flex">
<view class="px-4 py-2 bg-blue-500 text-white rounded">按钮 1</view>
<view class="px-4 py-2 bg-green-500 text-white rounded">按钮 2</view>
</view>
<!-- 使用主题变量 -->
<view class="mt-4 p-4 rounded" style="background-color: var(--theme-colors-primary);">
<text class="text-white">主题按钮</text>
</view>
</view>
</template>
3. 运行项目
HBuilderX 运行项目, 插件会自动生成 style/css/uno.css 文件,包含所有使用的样式。
⚙️ 配置选项
基础配置
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
outputDir |
string |
'style/css' |
CSS 文件输出目录(相对于项目根目录) |
filename |
string |
'uno.css' |
生成的 CSS 文件名 |
watch |
boolean |
true |
是否监听文件变化并自动重新生成 CSS |
cache |
boolean |
true |
是否启用文件缓存以提升构建速度 |
cacheDir |
string |
'.hbuilderx/.cache/unocss-uni' |
缓存目录路径(相对于项目根目录) |
include |
string[] |
['pages/**/*.uvue'] |
要扫描的文件匹配模式(支持 glob) |
exclude |
string[] |
['node_modules/**', 'uni_modules/**', 'components/**'] |
排除的文件匹配模式 |
verbose |
boolean |
false |
是否输出详细日志,用于调试 |
strict |
boolean |
false |
是否启用严格模式(遇到错误时抛出异常) |
UnoCSS 配置
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
config |
UserConfig |
{} |
UnoCSS 原生配置,用于自定义规则、预设、主题等 |
defaults |
UserConfigDefaults |
undefined |
UnoCSS 默认配置 |
UCSS 转换配置
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ucssTransform.verbose |
boolean |
false |
UCSS 转换器的详细日志 |
ucssTransform.strict |
boolean |
false |
UCSS 转换器的严格模式 |
ucssTransform.removeInvalid |
boolean |
true |
是否移除不符合 UCSS 规范的属性 |
ucssTransform.forbiddenProperties |
string[] |
[] |
额外需要禁止的 CSS 属性 |
ucssTransform.unitConvert.enabled |
boolean |
true |
是否启用单位转换 |
ucssTransform.unitConvert.baseFontSize |
number |
16 |
rem/em 转换基准值(1rem = Npx) |
ucssTransform.unitConvert.viewportWidth |
number |
750 |
vw/vmin/vmax 转换基准值(设计稿宽度) |
ucssTransform.unitConvert.viewportHeight |
number |
1334 |
vh/vmin/vmax 转换基准值(设计稿高度) |
ucssTransform.unitConvert.customConverters |
Record<string, (value: number) => string> |
{} |
自定义单位转换器 |
预设主题配置
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
presetTheme.theme |
Record<string, ThemeColors> |
{} |
多主题配置,支持任意数量的主题(light、dark、ocean、forest 等) |
presetTheme.prefix |
string |
'theme' |
CSS 变量前缀,生成如 --theme-colors-primary |
presetTheme.rootSelector |
string |
'.app' |
默认主题(light)的根元素选择器 |
🔧 高级配置
1. 使用自定义 UnoCSS 预设
import { defineConfig } from 'vite'
import unocssForUniAppX from './uni_modules/kux-vite-unocss'
import { presetUno } from 'unocss'
export default defineConfig({
plugins: [
unocssForUniAppX({
config: {
// 自定义预设
presets: [
presetUno()
],
// 自定义主题
theme: {
colors: {
primary: '#007AFF',
secondary: '#5856D6',
success: '#34C759',
warning: '#FF9500',
danger: '#FF3B30'
},
spacing: {
'safe-top': 'env(safe-area-inset-top)',
'safe-bottom': 'env(safe-area-inset-bottom)'
}
},
// 自定义快捷方式
shortcuts: {
'btn': 'px-4 py-2 rounded bg-primary text-white font-medium',
'card': 'bg-white rounded-lg shadow-sm p-4',
'flex-center': 'flex items-center justify-center'
},
// 自定义规则
rules: [
[/^text-shadow-(sm|md|lg)$/, ([, size]) => {
const shadows = {
'sm': '0 1px 2px rgba(0,0,0,0.1)',
'md': '0 2px 4px rgba(0,0,0,0.1)',
'lg': '0 4px 8px rgba(0,0,0,0.1)'
};
return { 'text-shadow': shadows[size] };
}]
],
// 自定义变体
variants: [
(matcher) => {
if (!matcher.startsWith('dark:')) return matcher;
return {
matcher: matcher.slice(5),
selector: (s) => `[data-theme="dark"] ${s}, .dark ${s}`
};
}
]
}
})
]
})
2. 自定义扫描范围
unocssForUniAppX({
include: [
'pages/**/*.uvue',
'components/**/*.vue',
'src/**/*.uvue',
'layouts/**/*.vue'
],
exclude: [
'node_modules/**',
'uni_modules/**',
'components/external/**',
'**/*.test.*'
]
})
3. 完整配置示例
import { defineConfig } from 'vite'
import unocssForUniAppX from './uni_modules/kux-vite-unocss'
import { presetUno } from 'unocss'
export default defineConfig({
plugins: [
unocssForUniAppX({
// 基础配置
outputDir: 'style/css',
filename: 'uno.css',
watch: true,
cache: true,
cacheDir: '.hbuilderx/.cache/unocss-uni',
// 扫描范围
include: ['pages/**/*.uvue'],
exclude: ['node_modules/**', 'uni_modules/**', 'components/**'],
// 日志配置
verbose: false,
strict: false,
// 主题配置(明亮/暗黑模式)
presetTheme: {
prefix: 'theme',
rootSelector: '.app',
theme: {
light: {
colors: {
primary: '#007AFF',
success: '#34C759',
gray: {
50: '#F9FAFB',
100: '#F3F4F6',
800: '#1F2937',
900: '#111827'
}
}
},
dark: {
colors: {
primary: '#0A84FF',
success: '#30D158',
gray: {
50: '#1F2937',
100: '#374151',
800: '#F9FAFB',
900: '#FFFFFF'
}
}
}
}
},
// UnoCSS 配置
config: {
presets: [
presetUno()
],
shortcuts: {
'btn': 'px-4 py-2 rounded bg-[var(--theme-colors-primary)] text-white'
}
},
// UCSS 转换配置
ucssTransform: {
verbose: false,
strict: false,
removeInvalid: true,
unitConvert: {
enabled: true,
baseFontSize: 16,
viewportWidth: 750,
viewportHeight: 1334
}
}
})
]
})
🎨 CSS 主题配置(多主题支持)
插件支持通过 presetTheme 配置自动生成的 CSS 变量,支持任意数量的主题,不限于明亮/暗黑模式。
基础配置
在 vite.config.ts 中配置主题:
import { defineConfig } from 'vite'
import unocssForUniAppX from './uni_modules/kux-vite-unocss'
export default defineConfig({
plugins: [
unocssForUniAppX({
// 主题配置
presetTheme: {
// 主题前缀,生成的 CSS 变量前缀
// 例如:--theme-colors-primary, --theme-colors-success-6
prefix: 'theme',
// 根元素选择器,用于应用默认主题(通常是 light)
rootSelector: '.app',
// 主题颜色配置 - 支持任意数量的主题
theme: {
// 明亮模式
light: {
colors: {
// 基础颜色
primary: '#007AFF',
secondary: '#5856D6',
success: '#34C759',
warning: '#FF9500',
danger: '#FF3B30',
// 灰度颜色
gray: {
50: '#F9FAFB',
100: '#F3F4F6',
200: '#E5E7EB',
300: '#D1D5DB',
400: '#9CA3AF',
500: '#6B7280',
600: '#4B5563',
700: '#374151',
800: '#1F2937',
900: '#111827'
}
}
},
// 暗黑模式
dark: {
colors: {
// 基础颜色
primary: '#0A84FF',
secondary: '#5E5CE6',
success: '#30D158',
warning: '#FF9F0A',
danger: '#FF453A',
// 灰度颜色
gray: {
50: '#1F2937',
100: '#374151',
200: '#4B5563',
300: '#6B7280',
400: '#9CA3AF',
500: '#D1D5DB',
600: '#E5E7EB',
700: '#F3F4F6',
800: '#F9FAFB',
900: '#FFFFFF'
}
}
},
// 海洋主题(自定义)
ocean: {
colors: {
primary: '#00A8E8',
secondary: '#007EA7',
success: '#00F5D4',
background: '#CAF0F8',
text: '#03045E'
}
},
// 森林主题(自定义)
forest: {
colors: {
primary: '#34C759',
secondary: '#30B0C7',
success: '#4CD964',
background: '#F8FAF0',
text: '#1B4332'
}
},
// 日落主题(自定义)
sunset: {
colors: {
primary: '#FF9500',
secondary: '#FF3B30',
success: '#FFCC00',
background: '#FFF9E6',
text: '#2C1B00'
}
}
}
}
})
]
})
生成的 CSS 变量
插件会自动为每个主题生成对应的 CSS 变量:
/* 明亮模式变量(使用 rootSelector) */
.app {
--theme-colors-primary: #007AFF;
--theme-colors-secondary: #5856D6;
--theme-colors-success: #34C759;
--theme-colors-warning: #FF9500;
--theme-colors-danger: #FF3B30;
--theme-colors-gray-50: #F9FAFB;
--theme-colors-gray-100: #F3F4F6;
/* ... 其他灰度颜色 */
}
/* 暗黑模式变量 */
.dark {
--theme-colors-primary: #0A84FF;
--theme-colors-secondary: #5E5CE6;
--theme-colors-success: #30D158;
--theme-colors-warning: #FF9F0A;
--theme-colors-danger: #FF453A;
--theme-colors-gray-50: #1F2937;
--theme-colors-gray-100: #374151;
/* ... 其他灰度颜色 */
}
/* 海洋主题 */
.ocean {
--theme-colors-primary: #00A8E8;
--theme-colors-secondary: #007EA7;
--theme-colors-success: #00F5D4;
--theme-colors-background: #CAF0F8;
--theme-colors-text: #03045E;
}
/* 森林主题 */
.forest {
--theme-colors-primary: #34C759;
--theme-colors-secondary: '#30B0C7';
--theme-colors-success: #4CD964;
--theme-colors-background: #F8FAF0;
--theme-colors-text: #1B4332;
}
/* 日落主题 */
.sunset {
--theme-colors-primary: #FF9500;
--theme-colors-secondary: #FF3B30;
--theme-colors-success: #FFCC00;
--theme-colors-background: #FFF9E6;
--theme-colors-text: #2C1B00';
}
在代码中使用主题变量
1. 在 UnoCSS 配置中使用
export default defineConfig({
plugins: [
unocssForUniAppX({
presetTheme: {
prefix: 'theme',
theme: {
light: {
colors: {
primary: '#007AFF',
success: '#34C759'
}
},
dark: {
colors: {
primary: '#0A84FF',
success: '#30D158'
}
}
}
},
config: {
// 在 UnoCSS 配置中引用主题变量
shortcuts: {
'btn-primary': 'bg-[var(--theme-colors-primary)] text-white',
'text-success': 'text-[var(--theme-colors-success)]'
}
}
})
]
})
2. 在模板中使用
<template>
<view class="app">
<!-- 使用 CSS 变量 -->
<view class="card" style="background-color: var(--theme-colors-primary);">
<text class="text-white">主要按钮</text>
</view>
<!-- 使用 UnoCSS 类名 -->
<view class="bg-[var(--theme-colors-success)] p-4 rounded">
<text>成功状态</text>
</view>
<!-- 暗黑模式适配 -->
<view class="bg-[var(--theme-colors-gray-800)] dark">
<text>暗黑模式背景</text>
</view>
</view>
</template>
<style>
/* 在样式中直接使用 */
.card {
border-radius: 8px;
padding: 16px;
background-color: var(--theme-colors-primary);
}
.text-primary {
color: var(--theme-colors-primary);
}
</style>
3. 在 UTS 中动态切换多主题
方法 1:在 store 中定义多主题状态
// store/theme.uts
type ThemeType = 'light' | 'dark' | 'ocean' | 'forest' | 'sunset';
type State = {
currentTheme: ThemeType;
isSystemTheme: boolean;
}
export const state = reactive({
currentTheme: 'light' as ThemeType,
isSystemTheme: true,
} as State)
// 设置主题
export const setTheme = (theme: ThemeType) => {
state.currentTheme = theme;
state.isSystemTheme = false;
// Web 端通过 class 切换
// #ifdef WEB
const rootElement = document.querySelector('.app');
if (rootElement) {
// 移除所有主题类
const themeClasses = ['dark', 'ocean', 'forest', 'sunset'];
themeClasses.forEach(themeClass => {
rootElement.classList.remove(themeClass);
});
// 添加新主题类(除了 light)
if (theme !== 'light') {
rootElement.classList.add(theme);
}
}
// #endif
// App 端使用系统主题 API
// #ifdef APP
if (theme === 'light') {
uni.setAppTheme({ theme: 'light' });
} else if (theme === 'dark') {
uni.setAppTheme({ theme: 'dark' });
}
// 注意:自定义主题在 App 端需要结合 class 切换
// #endif
};
// 检测系统主题
export const detectSystemTheme = () => {
// #ifdef WEB || MP-WEIXIN
const info = uni.getAppBaseInfo();
const isDark = info.hostTheme === 'dark';
setTheme(isDark ? 'dark' : 'light');
state.isSystemTheme = true;
uni.onHostThemeChange((result) => {
const isDarkMode = result.hostTheme === 'dark';
setTheme(isDarkMode ? 'dark' : 'light');
});
// #endif
// #ifdef APP
uni.setAppTheme({ theme: "auto" });
uni.getSystemInfo({
success: (res: GetSystemInfoResult) => {
const appTheme = res.appTheme == "auto" ? res.osTheme! : res.appTheme!;
setTheme(appTheme == "dark" ? 'dark' : 'light');
state.isSystemTheme = true;
}
});
uni.onOsThemeChange((res: OsThemeChangeResult) => {
setTheme(res.osTheme == "dark" ? 'dark' : 'light');
state.isSystemTheme = true;
});
uni.onAppThemeChange((res: AppThemeChangeResult) => {
setTheme(res.appTheme == "dark" ? 'dark' : 'light');
state.isSystemTheme = true;
});
// #endif
};
// 保存主题到本地存储
export const saveThemePreference = (theme: ThemeType) => {
uni.setStorageSync('theme-preference', theme);
};
// 加载保存的主题
export const loadThemePreference = (): ThemeType | null => {
const saved = uni.getStorageSync('theme-preference');
return saved || null;
};
// 初始化主题
export const initTheme = () => {
const savedTheme = loadThemePreference();
if (savedTheme) {
setTheme(savedTheme);
} else {
detectSystemTheme();
}
};
方法 2:在页面中使用多主题切换器
<template>
<view class="app" :class="[currentTheme, { 'dark': currentTheme === 'dark' }]">
<view class="container">
<!-- 当前主题显示 -->
<view class="status-bar">
<text class="text-lg">当前主题:{{ themeLabels[currentTheme] }}</text>
</view>
<!-- 主题预览 -->
<view class="preview-section p-4 rounded-lg">
<text class="text-xl font-bold mb-4">主题颜色预览</text>
<view class="color-grid">
<view class="color-item" v-for="color in primaryColors" :key="color">
<view :style="{ backgroundColor: color }" class="color-box"></view>
<text class="text-xs">{{ color }}</text>
</view>
</view>
</view>
<!-- 主题切换按钮 -->
<view class="theme-buttons mt-6">
<view
v-for="theme in themes"
:key="theme.value"
class="theme-btn"
:class="{ 'active': currentTheme === theme.value }"
@click="selectTheme(theme.value)"
>
<view class="theme-icon" :style="{ backgroundColor: theme.color }"></view>
<text class="theme-name">{{ theme.label }}</text>
</view>
</view>
<!-- 跟随系统开关 -->
<view class="system-toggle mt-4">
<text class="mr-2">跟随系统主题</text>
<switch :checked="isSystemTheme" @change="onSystemToggle" />
</view>
</view>
</view>
</template>
<script setup>
import { state, setTheme, detectSystemTheme, saveThemePreference } from '@/store/theme'
type ThemeType = 'light' | 'dark' | 'ocean' | 'forest' | 'sunset';
// 主题配置
const themes = [
{ value: 'light' as ThemeType, label: '明亮', color: '#007AFF' },
{ value: 'dark' as ThemeType, label: '暗黑', color: '#0A84FF' },
{ value: 'ocean' as ThemeType, label: '海洋', color: '#00A8E8' },
{ value: 'forest' as ThemeType, label: '森林', color: '#34C759' },
{ value: 'sunset' as ThemeType, label: '日落', color: '#FF9500' }
];
const themeLabels: Record<ThemeType, string> = {
light: '明亮',
dark: '暗黑',
ocean: '海洋',
forest: '森林',
sunset: '日落'
};
const primaryColors = [
'var(--theme-colors-primary)',
'var(--theme-colors-secondary)',
'var(--theme-colors-success)',
'var(--theme-colors-warning)',
'var(--theme-colors-danger)'
];
const currentTheme = ref<ThemeType>(state.currentTheme);
const isSystemTheme = ref(state.isSystemTheme);
// 选择主题
const selectTheme = (theme: ThemeType) => {
setTheme(theme);
currentTheme.value = theme;
isSystemTheme.value = false;
saveThemePreference(theme);
};
// 切换跟随系统
const onSystemToggle = (e: UniSwitchChangeEvent) => {
if (e.detail.value) {
detectSystemTheme();
isSystemTheme.value = true;
} else {
isSystemTheme.value = false;
}
};
</script>
<style>
.container {
padding: 20px;
min-height: 100vh;
background-color: var(--theme-colors-background);
color: var(--theme-colors-text);
}
.status-bar {
text-align: center;
padding: 20px 0;
}
.preview-section {
background-color: #ffffff;
margin-bottom: 20px;
}
.color-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
}
.color-item {
display: flex;
flex-direction: column;
align-items: center;
}
.color-box {
width: 50px;
height: 50px;
border-radius: 8px;
margin-bottom: 8px;
}
.theme-buttons {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.theme-btn {
display: flex;
align-items: center;
padding: 12px 20px;
border-radius: 12px;
background-color: #f0f0f0;
border: 2px solid transparent;
}
.theme-btn.active {
border-color: var(--theme-colors-primary);
background-color: var(--theme-colors-background);
}
.theme-icon {
width: 30px;
height: 30px;
border-radius: 50%;
margin-right: 12px;
}
.theme-name {
font-size: 16px;
font-weight: 500;
}
.system-toggle {
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
background-color: #ffffff;
border-radius: 12px;
}
</style>
方法 3:使用 uni-app 的主题 API(App 端)
// #ifdef APP
// 切换到系统定义的明亮/暗黑主题
uni.setAppTheme({
theme: 'light' // 'light' | 'dark' | 'auto'
});
// 监听系统主题变化
uni.onOsThemeChange((res) => {
console.log('系统主题变化:', res.osTheme);
});
// 自定义主题需要结合 class 切换
// 注意:uni-app 只内置了 light/dark/auto 三种主题
// 其他自定义主题(ocean、forest 等)需要通过 class 实现
// #endif
颜色格式要求
- 十六进制:
#007AFF,#FF453A - RGB:
rgb(0, 122, 255)- 会被转换为十六进制 - 不支持: 渐变、透明度等复杂格式
实际应用示例
// vite.config.ts
export default defineConfig({
plugins: [
unocssForUniAppX({
presetTheme: {
prefix: 'theme',
rootSelector: '.app',
theme: {
light: {
colors: {
primary: '#007AFF',
background: '#FFFFFF',
text: '#000000'
}
},
dark: {
colors: {
primary: '#0A84FF',
background: '#000000',
text: '#FFFFFF'
}
}
}
},
config: {
shortcuts: {
'theme-bg': 'bg-[var(--theme-colors-background)]',
'theme-text': 'text-[var(--theme-colors-text)]',
'theme-primary': 'bg-[var(--theme-colors-primary)] text-white'
}
}
})
]
})
<!-- pages/index/index.uvue -->
<template>
<view class="app theme-bg theme-text" :class="{ 'dark': isDarkMode }">
<view class="p-4">
<view class="theme-primary rounded-lg p-4">
<text>主题按钮</text>
</view>
<view class="mt-4" @click="toggleTheme">
<text>切换主题</text>
</view>
</view>
</view>
</template>
<script setup>
const isDarkMode = ref(false)
function toggleTheme() {
isDarkMode.value = !isDarkMode.value
}
</script>
生成的 CSS 文件示例
/* style/css/uno.css */
.app {
--theme-colors-primary: #007AFF;
--theme-colors-background: #FFFFFF;
--theme-colors-text: #000000;
}
.dark {
--theme-colors-primary: #0A84FF;
--theme-colors-background: #000000;
--theme-colors-text: #FFFFFF;
}
.theme-bg {
background-color: var(--theme-colors-background);
}
.theme-text {
color: var(--theme-colors-text);
}
.theme-primary {
background-color: var(--theme-colors-primary);
color: #FFFFFF;
}
🎨 支持的 CSS 特性
下面仅为部分说明,完整请参考 UCSS 说明
✅ 完全支持的特性
| 类别 | 特性 | 示例 | 说明 |
|---|---|---|---|
| 选择器 | 类选择器 | .class-name |
标准类名 |
| 伪类 | :hover, :focus |
悬停、聚焦等状态 | |
| 伪元素 | ::before, ::after |
伪元素选择器 | |
| 颜色 | RGB/HSL 现代格式 | rgb(255 149 0 / 0.5) |
转换为 rgba(255, 149, 0, 0.5) |
| 透明度变量 | var(--un-bg-opacity) |
保留 CSS 变量 | |
| 单位 | rem/em 转 px | 1rem → 16px |
基于 baseFontSize |
| vw/vh 转 rpx | 1vw → 7.5rpx |
基于 viewportWidth | |
| vmin/vmax | 1vmin → 7.5rpx |
取最小/最大值 | |
| 绝对单位 | 1cm, 1in 等 |
转换为 px | |
| 函数 | calc() | calc(1rem + 10px) |
递归转换内部单位 |
| var() | var(--color) |
保留不变 | |
| env() | env(safe-area-inset-top) |
保留不变 | |
| url() | url(/image.png) |
保留不变 | |
| 特殊类 | px-{n}rem | .px-1rem |
保留类名,转换样式 |
| Attributify | 属性语法 | bg-blue, text-red |
⚠️ 不支持 (uni-app x 限制) |
❌ 限制或转换的特性
| 类别 | 特性 | 处理方式 | 说明 |
|---|---|---|---|
| 布局 | float, grid, columns |
移除 | 不支持的布局属性 |
flex, flex-grow |
保留 | 但值中的单位不转换 | |
| 过渡 | transition-timing-function |
移除 | 不支持的过渡函数 |
transition-* |
保留 | 但不转换单位 | |
| 变换 | transform |
保留 | 但不转换内部单位 |
| 动画 | animation |
保留 | 但不转换时间单位 |
| 复杂@规则 | @keyframes |
移除 | uni-app x 不支持 |
@media |
移除 | 建议在代码中处理响应式 | |
@font-face |
保留 | 支持字体定义 | |
| CSS 函数 | min(), max() |
移除 | 不支持的函数 |
clamp() |
移除 | 不支持的函数 |
🔍 CSS 转换示例
1. 颜色格式转换
/* 转换前:现代 RGB 空格分隔格式 */
.bg-primary {
background-color: rgb(0 122 255 / var(--un-bg-opacity));
}
.text-gray-800 {
color: rgb(31 41 55 / var(--un-text-opacity));
}
.border-color {
border-color: rgb(255 149 0 / 0.5);
}
/* 转换后:兼容的 RGBA 格式 */
.bg-primary {
background-color: rgba(0, 122, 255, var(--un-bg-opacity));
}
.text-gray-800 {
color: rgba(31, 41, 55, var(--un-text-opacity));
}
.border-color {
border-color: rgba(255, 149, 0, 0.5);
}
2. 单位转换
/* 转换前:现代单位 */
.rem-unit {
padding: 1rem;
margin: 0.5rem 1rem;
}
.vw-unit {
width: 50vw;
height: 100vh;
}
.em-unit {
font-size: 1.5em;
line-height: 1.2; /* line-height 保持不变 */
}
/* 转换后:兼容单位(默认配置) */
.rem-unit {
padding: 16px;
margin: 8px 16px;
}
.vw-unit {
width: 375rpx; /* 50 * 750 / 100 */
height: 1334rpx; /* 100 * 1334 / 100 */
}
.em-unit {
font-size: 24px; /* 1.5 * 16 */
line-height: 1.2; /* 保持不变 */
}
3. px-rem 特殊类处理
/* 转换前:自定义 px-rem 类 */
.px-1rem {
padding-left: 1rem;
padding-right: 1rem;
}
.px-2rem {
margin: 2rem;
}
/* 转换后:保留类名,转换样式 */
.px-1rem {
padding-left: 16px;
padding-right: 16px;
}
.px-2rem {
margin: 32px;
}
4. !important 处理
/* 转换前 */
.btn {
background-color: rgb(0 122 255 / var(--un-bg-opacity)) !important;
padding: 1rem !important;
}
/* 转换后 */
.btn {
background-color: rgba(0, 122, 255, var(--un-bg-opacity)) !important;
padding: 16px !important;
}
5. calc() 函数转换
/* 转换前 */
.calc-example {
width: calc(100% - 2rem);
height: calc(50vh + 10px);
}
/* 转换后 */
.calc-example {
width: calc(100% - 32px);
height: calc(667rpx + 10px); /* 50 * 1334 / 100 */
}
6. 完整转换流程示例
/* UnoCSS 生成的原始 CSS */
.btn {
margin-top: 120px;
background-color: rgb(0 122 255 / var(--un-bg-opacity)) !important;
padding-left: 16px;
padding-right: 16px;
font-size: 1rem;
}
.safe-area {
padding-top: env(safe-area-inset-top);
}
.px-1rem {
padding-left: 1rem;
padding-right: 1rem;
}
/* 插件转换后的最终输出 */
.btn{margin-top:120px;background-color:rgba(0,122,255,var(--un-bg-opacity))!important;padding-left:16px;padding-right:16px;font-size:16px}.safe-area{padding-top:env(safe-area-inset-top)}.px-1rem{padding-left:16px;padding-right:16px}
📁 输出文件结构
项目根目录/
├── stype/
│ └── css/
│ └── uno.css # 生成的 CSS 文件(压缩后)
├── pages/
│ └── index/
│ └── index.uvue # 使用 UnoCSS 的页面
├── .hbuilderx/
│ └── .cache/
│ └── unocss-uni/ # 缓存目录
│ └── cache.json # 缓存数据
└── vite.config.ts # Vite 配置文件
生成的 CSS 文件示例
/* style/css/uno.css */
.btn{margin-top:120px;margin-bottom:120px;border-width:0px!important;border-radius:20px;--un-bg-opacity:1!important;background-color:rgba(0,122,255,var(--un-bg-opacity))!important;padding-left:16px;padding-right:16px;padding-top:8px;padding-bottom:8px;--un-text-opacity:1!important;color:rgba(255,255,255,var(--un-text-opacity))!important;font-weight:500;transition-duration:200ms}
.safe-top{padding-top:env(safe-area-inset-top)}
.flex{display:flex}
.bg-warning{--un-bg-opacity:1;background-color:rgba(255,149,0,var(--un-bg-opacity))}
.px-1rem{padding-left:16px;padding-right:16px}
🎯 使用示例
完整项目示例
vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import unocssForUniAppX from './uni_modules/kux-vite-unocss'
export default defineConfig({
plugins: [
uni(),
unocssForUniAppX({
outputDir: 'style/css',
filename: 'uno.css',
watch: true,
cache: true,
verbose: false,
config: {
theme: {
colors: {
primary: '#007AFF',
secondary: '#5856D6',
success: '#34C759',
warning: '#FF9500',
danger: '#FF3B30'
}
},
shortcuts: {
'btn': 'px-4 py-2 rounded bg-primary text-white font-medium',
'card': 'bg-white rounded-lg shadow-sm p-4'
}
}
})
]
})
pages/index/index.uvue
<template>
<view class="container">
<!-- 基础样式 -->
<view class="p-4 bg-white rounded-lg shadow-md">
<text class="text-xl font-bold text-gray-800">Hello UnoCSS</text>
<!-- 按钮组件 -->
<view class="mt-4 flex gap-2">
<view class="btn">主要按钮</view>
<view class="btn bg-secondary">次要按钮</view>
</view>
<!-- px-rem 特殊类 -->
<view class="px-1rem mt-4">
<text>固定间距的内容</text>
</view>
<!-- 安全区域 -->
<view class="safe-top mt-4">
<text>安全区域顶部</text>
</view>
</view>
</view>
</template>
<style>
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
</style>
生成的 CSS 分析
/* 1. 基础工具类 */
.p-4 { padding: 16px; }
.bg-white { background-color: #ffffff; }
.rounded-lg { border-radius: 8px; }
.shadow-md { box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
.text-xl { font-size: 20px; }
.font-bold { font-weight: 700; }
.text-gray-800 { color: rgba(31,41,55,1); }
.mt-4 { margin-top: 16px; }
.flex { display: flex; }
.gap-2 { gap: 8px; }
/* 2. 自定义快捷方式 */
.btn {
padding: 8px 16px;
border-radius: 4px;
background-color: rgba(0,122,255,1);
color: rgba(255,255,255,1);
font-weight: 500;
}
/* 3. px-rem 特殊类(保留类名,转换样式) */
.px-1rem {
padding-left: 16px;
padding-right: 16px;
}
/* 4. 安全区域 */
.safe-top {
padding-top: env(safe-area-inset-top);
}
🔧 工作原理
完整处理流程
项目启动
↓
1. 文件扫描
├─ 读取 include 匹配的文件
├─ 排除 exclude 匹配的文件
└─ 使用 glob 模式匹配
↓
2. 类名提取
├─ 解析 class="..." 属性
├─ 识别 UnoCSS 变体 (hover:, dark:, sm:)
└─ 去重并存储到全局集合
↓
3. 缓存检查
├─ 计算文件哈希
├─ 检查缓存是否有效(24小时内)
└─ 缓存命中则跳过提取
↓
4. CSS 生成
├─ 调用 UnoCSS 生成器
├─ 应用所有预设和规则
└─ 生成原始 CSS
↓
5. 颜色转换 (UnoColorConverter)
├─ rgb(255 149 0 / var(--un-bg-opacity))
└─ 转换为 rgba(255, 149, 0, var(--un-bg-opacity))
↓
6. UCSS 转换 (UcssTransformer)
├─ 移除注释
├─ 处理 px-{n}rem 特殊类
├─ 解析和验证 CSS 规则
├─ 转换颜色格式
├─ 移除不支持的 @规则
├─ 移除不支持的 CSS 函数
├─ 单位转换 (rem/em/vw/vh → px/rpx)
└─ 压缩 CSS
↓
7. 文件输出
├─ 确保输出目录存在
├─ 写入 CSS 文件
└─ 保存缓存到磁盘
↓
热更新监听(如果启用)
关键组件
1. 类名提取器 (extractClassesFromFile)
- 匹配
class="..."属性 - ⚠️ 不支持 Attributify 语法(uni-app x 限制)
- 识别 UnoCSS 变体
- 自动去重
2. 缓存系统
- 基于文件内容哈希
- 24小时有效期
- 支持磁盘持久化
- 增量构建优化
3. UnoCSS 生成器
- 使用
@unocss/core - 支持所有官方预设
- 完全自定义配置
4. 颜色转换器 (UnoColorConverter)
- 转换现代 RGB 空格分隔格式
- 支持背景、文本、边框颜色
- 保留 CSS 变量和透明度
5. UCSS 转换器 (UcssTransformer)
- removeComments: 移除 CSS 注释
- parseAndTransformRules: 整体解析和转换
- handlePxRemClasses: 处理
.px-{n}rem类 - transformSingleRule: 转换单个规则
- transformSelector: 验证选择器
- transformRulesContent: 处理规则内容
- handlePxRemClasses: 处理
- normalizeColorCalculations: 颜色格式标准化
- convertColorFormats: 颜色函数转换
- removeUnsupportedAtRules: 移除不支持的 @规则
- removeUnsupportedFunctions: 移除不支持的函数
- normalizeUnits: 单位转换核心
- minifyCss: 压缩输出
特殊处理
.px-{n}rem 类
// 输入
.px-1rem { padding: 1rem; }
// 处理流程
1. 匹配正则: /\.px-(\d+(?:\.\d+)?)rem\s*\{([^}]+)\}/
2. 提取 rem 值: 1
3. 转换样式: padding → 16px
4. 保留类名: .px-1rem
// 输出
.px-1rem { padding: 16px; }
单位转换
// 支持的单位转换
'rem' → 'px' (1rem = 16px)
'em' → 'px' (1em = 16px)
'vw' → 'rpx' (1vw = 7.5rpx, 基于 750)
'vh' → 'rpx' (1vh = 13.34rpx, 基于 1334)
'vmin' → 'rpx' (取 vw 和 vh 的最小值)
'vmax' → 'rpx' (取 vw 和 vh 的最大值)
'cm' → 'px' (1cm = 37.795px)
'mm' → 'px' (1mm = 3.7795px)
'in' → 'px' (1in = 96px)
'pt' → 'px' (1pt = 1.333px)
'pc' → 'px' (1pc = 16px)
跳过转换的属性
line-height: 保留 em 单位word-spacing,letter-spacing: 保留单位z-index,opacity: 纯数字flex,flex-grow,flex-shrink,order: 数字值grid-row,grid-column: 网格行号animation-*,transition-*,transform-*: 保留原始格式
🚨 常见问题与故障排除
Q1: 为什么我的样式没有生成?
可能原因和解决方案:
-
文件路径问题
// 检查 include 配置是否包含你的文件 include: ['pages/**/*.uvue', 'pages/**/*.vue'] -
类名书写错误
<!-- ❌ 错误 --> <view class="px-1rem" /> <!-- ✅ 正确 --> <view class="px-1rem" /> -
被 exclude 排除
// 检查 exclude 配置 exclude: ['node_modules/**', 'uni_modules/**', 'components/**'] // 如果你的文件在 components 目录下,会被排除 -
查看日志
// 启用详细日志查看问题 unocssForUniAppX({ verbose: true })
Q2: 样式不更新或缓存问题
解决方案:
# 1. 清除插件缓存
rm -rf .hbuilderx/.cache/unocss-uni
# 2. 清除旧的 CSS 文件
rm -f style/css/uno.css
# 3. 重新构建插件
cd uni_modules/kux-vite-unocss && pnpm build
# 4. 重启开发服务器
或者禁用缓存:
unocssForUniAppX({
cache: false // 开发阶段可以禁用
})
Q3: 转换后的 CSS 格式错误
检查点:
-
确保使用最新版本
cd uni_modules/kux-vite-unocss git pull # 或重新下载插件 pnpm build -
清理所有缓存
rm -rf .hbuilderx/.cache/unocss-uni rm -f style/css/uno.css -
验证配置
// 确保 ucssTransform 配置正确 ucssTransform: { unitConvert: { enabled: true, baseFontSize: 16 } }
Q4: 自定义规则不生效
解决方案:
unocssForUniAppX({
config: {
rules: [
[/^custom-([a-z]+)$/, ([, name]) => {
return { 'custom-property': name };
}]
]
}
})
注意: 自定义规则生成的 CSS 也会经过 UCSS 转换器处理。
Q5: Attributify 模式不工作
当前不支持:
由于 uni-app x 框架的限制,插件当前不支持 Attributify 模式(即属性语法,如 <view bg-blue text-white>)。
解决方案:
请使用标准的 class 属性语法:
<!-- ✅ 正确(推荐) -->
<view class="bg-blue text-white p-4"></view>
<!-- ❌ 不支持 -->
<view bg-blue text-white p-4></view>
说明:
Attributify 模式虽然在标准 UnoCSS 中可用,但 uni-app x 框架对属性语法的解析存在限制,因此本插件暂不支持此功能。未来如果 uni-app x 框架支持,我们会考虑添加此功能。
Q6: rem 单位转换不正确
检查基准字体大小:
// 默认 1rem = 16px
ucssTransform: {
unitConvert: {
baseFontSize: 16 // 如果设计稿是 1rem = 20px,改为 20
}
}
验证转换:
/* 输入 */
.test { padding: 1rem; }
/* 输出(baseFontSize: 16) */
.test { padding: 16px; }
/* 输出(baseFontSize: 20) */
.test { padding: 20px; }
Q7: vw/vh 转换不符合预期
检查视口配置:
ucssTransform: {
unitConvert: {
viewportWidth: 750, // 设计稿宽度(默认)
viewportHeight: 1334 // 设计稿高度(默认)
}
}
转换计算:
/* 输入:设计稿宽度 750px */
.test { width: 50vw; }
/* 输出:50 * 750 / 100 = 375rpx */
.test { width: 375rpx; }
Q8: 构建时报错 "Cannot find module"
解决方案:
# 1. 安装依赖
cd uni_modules/kux-vite-unocss
pnpm install
# 2. 构建插件
pnpm build
# 3. 检查 dist 目录
ls -la dist/
# 应该有:index.mjs, index.d.ts, index.d.mts
Q9: 插件在 HBuilderX 中不工作
检查步骤:
- 确保插件在
uni_modules目录下 - 检查
vite.config.ts路径是否正确 - 重启 HBuilderX
- 清除 HBuilderX 缓存:工具 → 清除缓存
Q10: 如何验证插件是否正常工作?
测试方法:
-
启用详细日志
unocssForUniAppX({ verbose: true }) -
查看生成的 CSS
cat style/css/uno.css -
检查控制台输出
- 应该看到 "Found X unique classes"
- 应该看到 "CSS generated successfully"
-
验证转换结果
# 检查 .px-1rem 是否正确转换 grep "px-1rem" style/css/uno.css # 应该输出:.px-1rem{padding-left:16px;padding-right:16px}
Q11: 性能优化建议
大型项目优化:
unocssForUniAppX({
// 开发阶段
watch: true,
cache: true,
verbose: false,
// 生产构建
// watch: false,
// cache: true,
// 限制扫描范围
include: ['pages/**/*.uvue'],
exclude: [
'node_modules/**',
'uni_modules/**',
'components/**',
'**/*.test.*',
'**/*.spec.*'
],
// 性能配置
ucssTransform: {
verbose: false,
strict: false
}
})
Q12: 调试技巧
1. 查看中间状态
// 在 ucssTransformer.ts 中临时添加日志
console.log('After handlePxRemClasses:', css);
2. 测试转换器
import { UcssTransformer } from './uni_modules/kux-vite-unocss/src/ucssTransformer';
const transformer = new UcssTransformer({ verbose: true });
const result = transformer.transform('.px-1rem{padding:1rem}');
console.log(result); // 应该输出: .px-1rem{padding:16px}
3. 检查缓存内容
cat .hbuilderx/.cache/unocss-uni/cache.json
Q13: 已知限制
- 不支持 CSS Grid:uni-app x 的布局限制
- 不支持 @keyframes:需要使用 UTS 实现动画
- 不支持媒体查询:建议使用条件编译或 UTS
- 不支持伪元素 content:uni-app x 限制
- 部分 CSS 函数不支持:min(), max(), clamp() 等
Q14: 获取更多帮助
如果以上方案都无法解决问题:
-
查看详细日志
unocssForUniAppX({ verbose: true, strict: true }) -
检查版本兼容性
# 查看插件版本 cat uni_modules/kux-vite-unocss/package.json | grep version -
提交 Issue
- 提供最小复现案例
- 附上配置文件和错误日志
- 说明使用的 uni-app x 版本
-
查看更新日志
cat uni_modules/kux-vite-unocss/changelog.md
🔄 完整工作流程
开发阶段
-
启动开发服务器
# HBuilderX 运行项目 # 或 npm run dev -
插件初始化
- 加载缓存(如果启用)
- 扫描所有匹配文件
- 提取类名并去重
-
首次 CSS 生成
- 调用 UnoCSS 生成器
- 转换颜色格式
- UCSS 转换
- 写入
style/css/uno.css
-
热更新监听
- 监听文件变化
- 增量更新类名集合
- 防抖重新生成 CSS
生产构建
-
构建命令
npm run build -
优化处理
- 禁用热更新
- 启用缓存
- 压缩 CSS
- 生成最终文件
-
部署
style/css/uno.css随项目一起部署- 文件已优化,无需额外处理
📊 性能特点
优势
| 特性 | 说明 | 性能影响 |
|---|---|---|
| 缓存机制 | 文件哈希缓存 | ⚡⚡⚡⚡⚡ 极大提升 |
| 增量构建 | 只处理变化的文件 | ⚡⚡⚡⚡⚡ 极大提升 |
| 防抖更新 | 500ms 延迟批量处理 | ⚡⚡⚡⚡ 提升 |
| 类名去重 | 全局集合自动去重 | ⚡⚡⚡ 提升 |
| 按需生成 | 只生成使用的样式 | ⚡⚡⚡⚡ 极大提升 |
优化建议
大型项目(100+ 页面)
unocssForUniAppX({
cache: true,
cacheDir: '.hbuilderx/.cache/unocss-uni',
watch: false, // 构建时关闭监听
verbose: false,
include: ['pages/**/*.uvue'],
exclude: [
'node_modules/**',
'uni_modules/**',
'components/**',
'**/*.test.*',
'**/*.spec.*'
]
})
小型项目
unocssForUniAppX({
cache: true,
watch: true,
verbose: true // 开发阶段开启日志
})
🛠️ 集成指南
与 HBuilderX 集成
插件自动集成,无需额外配置。只需在 vite.config.ts 中添加插件即可。
与 CI/CD 集成
# 构建命令
npm run build
# 插件会自动:
# 1. 扫描文件
# 2. 生成 CSS
# 3. 输出到 style/css/uno.css
# 4. 保存缓存(可选)
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
开发流程
# 克隆仓库
git clone https://gitcode.com/uvuejs/kux-vite-plugin-unocss
cd kux-vite-plugin-unocss/uni_modules/kux-vite-unocss
# 安装依赖
pnpm install
# 构建插件
pnpm build
# 运行测试
npx tsx test_simple.ts
# 提交代码
git add .
git commit -m "feat: 添加新功能"
git push
📄 许可证
MIT © kux
🔗 相关链接
📝 更新日志
查看 CHANGELOG.md 了解最新更新和修复。
🧪 测试验证
插件提供了完整的功能测试套件,用于验证所有核心功能是否正常工作。
运行测试
# 在插件目录下运行完整测试
cd uni_modules/kux-vite-unocss
npx tsx test-all.mjs
# 仅测试多主题功能
npx tsx test-multitheme.mjs
测试模块
测试套件包含以下 5 个核心功能模块的测试:
1. 颜色格式转换测试 (UnoColorConverter)
测试内容:
- ✅ 背景颜色转换:
rgb(0 122 255 / var(--un-bg-opacity))→rgba(0, 122, 255, var(--un-bg-opacity)) - ✅ 文本颜色转换:
rgb(31 41 55 / var(--un-text-opacity))→rgba(31, 41, 55, var(--un-text-opacity)) - ✅ 边框颜色转换:
rgb(255 149 0 / var(--un-border-opacity))→rgba(255, 149, 0, var(--un-border-opacity))
测试用例数量: 3 个
2. 单位转换测试 (UCSS Transformer)
测试内容:
- ✅ rem 单位转换:
1rem→16px - ✅ em 单位转换:
1.5em→24px - ✅ vw 单位转换:
50vw→375rpx(基于 750 设计稿) - ✅ vh 单位转换:
100vh→1334rpx(基于 1334 设计稿) - ✅ vmin 单位转换:
10vmin→75rpx - ✅ vmax 单位转换:
10vmax→133.4rpx - ✅ 绝对单位转换:
cm,mm,in,pt,pc
测试用例数量: 12 个
3. 多主题功能测试 (PresetTheme)
测试内容:
- ✅ CSS 变量前缀正确: 使用
--前缀 (如--theme-colors-primary) - ✅ 选择器逻辑正确:
light主题使用rootSelector, 其他主题使用类选择器 - ✅ 颜色值正确转换: 转换为十六进制格式
- ✅ 色阶颜色正确生成: 支持
gray-50,gray-500等色阶
测试用例数量: 6 个
测试配置示例:
{
prefix: 'theme',
rootSelector: '.app',
theme: {
light: { colors: { primary: '#007AFF' } },
dark: { colors: { primary: '#0A84FF' } },
ocean: { colors: { primary: '#00A8E8' } }
}
}
生成的 CSS 示例:
.app {
--theme-colors-primary: #007aff;
}
.dark {
--theme-colors-primary: #0a84ff;
}
.ocean {
--theme-colors-primary: #00a8e8;
}
4. 类名提取测试 (ClassExtractor)
测试内容:
- ✅ 基础 class 属性提取:
<view class="p-4 bg-white">→['p-4', 'bg-white'] - ✅ 变体语法提取:
<view class="hover:bg-blue-500 dark:text-white"> - ✅ 空 class 处理: 正确处理空字符串
- ⚠️ Attributify 模式: 由于 uni-app x 框架限制,暂不支持
测试用例数量: 5 个
提取的类名类型:
- 标准 class 属性:
class="p-4 bg-white" - UnoCSS 变体:
hover:,focus:,dark:,sm:,md:等 - 状态伪类:
disabled,checked,first,last等
5. 缓存系统测试 (CacheSystem)
测试内容:
- ✅ 相同内容生成相同哈希
- ✅ 不同内容生成不同哈希
- ✅ 大小写敏感
- ✅ 空格敏感
- ✅ 空内容哈希处理
测试用例数量: 5 个
缓存特性:
- 基于文件内容哈希
- 24 小时缓存有效期
- 支持磁盘持久化
- 增量构建优化
测试输出示例
运行 npx tsx test-all.mjs 后,会看到详细的测试报告:
╔══════════════════════════════════════════════════════════╗
║ kux-vite-unocss 功能测试 ║
╚══════════════════════════════════════════════════════════╝
============================================================
📦 模块 1: 颜色格式转换测试 (UnoColorConverter)
============================================================
测试: 背景颜色转换
输入: .bg-primary { background-color: rgb(0 122 255 / var(--un-bg-opacity)); }
期望包含: rgba(0, 122, 255, var(--un-bg-opacity))
实际: .bg-primary { background-color: rgba(0, 122, 255, var(--un-bg-opacity)); }
✅ 通过
测试: 文本颜色转换
...
测试: 边框颜色转换
...
📊 颜色转换测试结果: 3/3 通过
============================================================
📦 模块 2: 单位转换测试 (UCSS Transformer)
============================================================
...
📊 单位转换测试结果: 12/12 通过
============================================================
📦 模块 3: 多主题功能测试 (PresetTheme)
============================================================
...
📊 多主题功能测试结果: 6/6 通过
============================================================
📦 模块 4: 类名提取测试 (ClassExtractor)
============================================================
...
📊 类名提取测试结果: 3/5 通过
============================================================
📦 模块 5: 缓存系统测试 (CacheSystem)
============================================================
...
📊 缓存系统测试结果: 5/5 通过
============================================================
📊 测试结果汇总
============================================================
颜色格式转换:
✅ 通过: 3
❌ 失败: 0
单位转换:
✅ 通过: 12
❌ 失败: 0
多主题功能:
✅ 通过: 6
❌ 失败: 0
类名提取:
✅ 通过: 3
❌ 失败: 2
缓存系统:
✅ 通过: 5
❌ 失败: 0
============================================================
总计: 31 个测试
通过: 29 ✅
失败: 2 ❌
成功率: 93.55%
============================================================
测试文件说明
test-all.mjs- 完整功能测试套件,包含所有 5 个模块的测试test-multitheme.mjs- 多主题功能专项测试
如何使用测试
1. 开发新功能时:
# 修改代码后运行测试
npx tsx test-all.mjs
# 如果只修改了多主题功能
npx tsx test-multitheme.mjs
2. 测试自定义配置:
修改测试文件中的配置,例如在 test-multitheme.mjs 中修改主题配置:
const presetThemeConfig = {
prefix: 'mytheme', // 修改前缀
rootSelector: '#app', // 修改选择器
theme: {
// 添加你的自定义主题
custom: {
colors: {
primary: '#FF5733',
secondary: '#C70039'
}
}
}
};
然后运行测试验证配置是否正确。
3. 回归测试:
在发布新版本前,运行完整测试套件确保所有功能正常:
# 清理缓存
rm -rf .hbuilderx/.cache/unocss-uni
# 运行完整测试
npx tsx test-all.mjs
# 构建插件
pnpm build
测试覆盖率
当前测试覆盖的功能:
| 模块 | 测试用例 | 覆盖率 |
|---|---|---|
| 颜色格式转换 | 3 | 100% |
| 单位转换 | 12 | 100% |
| 多主题功能 | 6 | 100% |
| 类名提取 | 5 | 60% |
| 缓存系统 | 5 | 100% |
| 总计 | 31 | 93.55% |
常见问题
Q: 测试失败怎么办?
如果测试失败,请检查:
- 确保所有依赖已安装:
pnpm install - 清理缓存后重试:
rm -rf node_modules/.cache - 查看详细错误信息,定位具体问题
Q: 如何添加新的测试用例?
在对应的测试函数中添加新的测试用例对象:
const testCases = [
{
name: '新测试用例',
input: '输入内容',
expected: '期望结果'
},
// 添加更多用例...
];
Q: 测试可以自动化吗?
可以。在 CI/CD 流程中添加测试步骤:
# .github/workflows/test.yml
- name: Run tests
run: |
cd uni_modules/kux-vite-unocss
pnpm install
npx tsx test-all.mjs
提示:如果在使用过程中遇到问题,请先查看常见问题章节,或启用详细日志进行调试。
文档主体由AI生成

收藏人数:
https://gitcode.com/uvuejs/kux-vite-plugin-unocss
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 3629
赞赏 26
下载 13075281
赞赏 1841
赞赏
京公网安备:11010802035340号