本章概述

本章将详细介绍如何安装和配置 UnoCSS,包括不同的安装方式、配置文件的详细说明、开发工具的集成以及 IDE 支持。通过本章学习,你将能够在任何项目中快速搭建 UnoCSS 开发环境。

安装方式

1. 使用包管理器安装

npm 安装

# 安装核心包
npm install -D unocss

# 安装常用预设
npm install -D @unocss/preset-uno @unocss/preset-wind @unocss/preset-icons

# 安装构建工具插件
npm install -D @unocss/vite  # Vite 项目
npm install -D @unocss/webpack  # Webpack 项目
npm install -D @unocss/postcss  # PostCSS 项目

yarn 安装

# 使用 yarn
yarn add -D unocss @unocss/preset-uno @unocss/preset-wind @unocss/preset-icons
yarn add -D @unocss/vite

pnpm 安装

# 使用 pnpm
pnpm add -D unocss @unocss/preset-uno @unocss/preset-wind @unocss/preset-icons
pnpm add -D @unocss/vite

2. CDN 方式

<!-- 开发环境 -->
<script src="https://cdn.jsdelivr.net/npm/@unocss/runtime/uno.global.js"></script>

<!-- 生产环境(压缩版) -->
<script src="https://cdn.jsdelivr.net/npm/@unocss/runtime/uno.global.min.js"></script>

3. 在线体验

<!-- UnoCSS Playground -->
<!-- 访问 https://unocss.dev/play/ 进行在线体验 -->

<!-- 快速原型 -->
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime/uno.global.js"></script>
  <script>
    window.__unocss = {
      rules: [
        ['text-red', { color: 'red' }],
        [/^text-(.+)$/, ([, color]) => ({ color })],
      ],
    }
  </script>
</head>
<body>
  <div class="text-blue-500 p-4">Hello UnoCSS!</div>
</body>
</html>

配置文件详解

1. 基础配置文件

uno.config.js

// uno.config.js
import { defineConfig } from 'unocss'

export default defineConfig({
  // 配置选项
})

uno.config.ts (TypeScript)

// uno.config.ts
import { defineConfig } from 'unocss'
import type { UserConfig } from 'unocss'

export default defineConfig({
  // 配置选项
} as UserConfig)

2. 完整配置示例

// uno.config.js
import {
  defineConfig,
  presetUno,
  presetWind,
  presetIcons,
  presetTypography,
  presetWebFonts,
  transformerDirectives,
  transformerVariantGroup,
} from 'unocss'

export default defineConfig({
  // 预设配置
  presets: [
    presetUno(),
    presetWind(),
    presetIcons({
      collections: {
        carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default),
        mdi: () => import('@iconify-json/mdi/icons.json').then(i => i.default),
      }
    }),
    presetTypography(),
    presetWebFonts({
      fonts: {
        sans: 'DM Sans',
        serif: 'DM Serif Display',
        mono: 'DM Mono',
      },
    }),
  ],
  
  // 自定义规则
  rules: [
    // 静态规则
    ['custom-rule', { color: 'red' }],
    
    // 动态规则
    [/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
    
    // 函数式规则
    [/^bg-gradient-(.+)$/, ([, color]) => ({
      background: `linear-gradient(45deg, ${color}, transparent)`
    })],
  ],
  
  // 快捷方式
  shortcuts: {
    // 静态快捷方式
    'btn': 'py-2 px-4 font-semibold rounded-lg shadow-md',
    'btn-green': 'text-white bg-green-500 hover:bg-green-700',
    
    // 动态快捷方式
    'btn-red': 'text-white bg-red-500 hover:bg-red-700',
    
    // 函数式快捷方式
    [/^btn-(.*)$/, ([, c]) => `bg-${c}-400 text-${c}-100 py-2 px-4 rounded`],
  },
  
  // 主题配置
  theme: {
    colors: {
      primary: {
        50: '#eff6ff',
        500: '#3b82f6',
        900: '#1e3a8a',
      },
      secondary: {
        50: '#f0f9ff',
        500: '#0ea5e9',
        900: '#0c4a6e',
      }
    },
    fontFamily: {
      custom: ['Custom Font', 'sans-serif'],
    },
    breakpoints: {
      xs: '320px',
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
      '2xl': '1536px',
    }
  },
  
  // 变体配置
  variants: [
    // 自定义变体
    (matcher) => {
      if (!matcher.startsWith('important:')) return matcher
      return {
        matcher: matcher.slice(10),
        body: (body) => {
          body.forEach((v) => {
            if (v[1]) v[1] += ' !important'
          })
          return body
        },
      }
    },
  ],
  
  // 转换器
  transformers: [
    transformerDirectives(),
    transformerVariantGroup(),
  ],
  
  // 安全列表
  safelist: [
    'prose',
    'prose-sm',
    'm-1',
    'text-red-500',
  ],
  
  // 阻止列表
  blocklist: [
    'container',
  ],
  
  // 内容配置
  content: {
    filesystem: [
      '**/*.{html,js,ts,jsx,tsx,vue,svelte}',
    ],
  },
  
  // 提取器配置
  extractors: [
    {
      extractor: (code) => {
        // 自定义提取逻辑
        return code.match(/[\w-:]+/g) || []
      },
      extensions: ['html', 'js', 'ts', 'jsx', 'tsx', 'vue', 'svelte'],
    },
  ],
  
  // 预检样式
  preflights: [
    {
      getCSS: ({ theme }) => `
        * {
          box-sizing: border-box;
        }
        body {
          font-family: ${theme.fontFamily?.sans?.join(', ')};
        }
      `
    }
  ],
  
  // 层级配置
  layers: {
    components: -1,
    default: 1,
    utilities: 2,
    shortcuts: 3,
  },
})

3. 配置文件位置

UnoCSS 会按以下顺序查找配置文件:

1. uno.config.{js,ts,mjs,mts}
2. unocss.config.{js,ts,mjs,mts}
3. package.json 中的 unocss 字段

构建工具集成

1. Vite 集成

基础配置

// vite.config.js
import { defineConfig } from 'vite'
import UnoCSS from 'unocss/vite'

export default defineConfig({
  plugins: [
    UnoCSS(),
  ],
})

高级配置

// vite.config.js
import { defineConfig } from 'vite'
import UnoCSS from 'unocss/vite'

export default defineConfig({
  plugins: [
    UnoCSS({
      // 内联配置(可选)
      uno: true,
      icons: true,
      attributify: true,
      
      // 配置文件路径
      configFile: './my-uno.config.ts',
      
      // 开发模式配置
      mode: 'global', // 'vue-scoped' | 'svelte-scoped' | 'shadow-dom'
      
      // HMR 配置
      hmrTopLevelAwait: false,
    }),
  ],
  
  // CSS 配置
  css: {
    transformer: 'postcss',
  },
})

入口文件配置

// main.js
import { createApp } from 'vue'
import App from './App.vue'

// 导入 UnoCSS 样式
import 'virtual:uno.css'

// 可选:导入预检样式
import '@unocss/reset/tailwind.css'

createApp(App).mount('#app')

2. Webpack 集成

// webpack.config.js
const UnoCSS = require('@unocss/webpack').default

module.exports = {
  plugins: [
    UnoCSS(),
  ],
  
  // 或者作为 loader
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: '@unocss/webpack',
            options: {
              // 配置选项
            }
          }
        ]
      }
    ]
  }
}

3. PostCSS 集成

// postcss.config.js
module.exports = {
  plugins: {
    '@unocss/postcss': {},
    autoprefixer: {},
  },
}
/* styles.css */
@unocss preflights;
@unocss default;

/* 自定义样式 */
.custom {
  @apply text-red-500 font-bold;
}

4. Nuxt 集成

// nuxt.config.js
export default defineNuxtConfig({
  modules: [
    '@unocss/nuxt',
  ],
  
  unocss: {
    // UnoCSS 配置
    uno: true,
    icons: true,
    attributify: true,
    
    // 或者引用配置文件
    // configFile: 'uno.config.ts',
  },
})

5. Next.js 集成

// next.config.js
const withUnoCSS = require('@unocss/next')

module.exports = withUnoCSS({
  // Next.js 配置
})
// _app.js
import 'uno.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

框架特定配置

1. Vue 项目配置

// uno.config.js
import { defineConfig, presetUno, presetAttributify } from 'unocss'

export default defineConfig({
  presets: [
    presetUno(),
    presetAttributify(),
  ],
  
  // Vue 特定配置
  extractors: [
    {
      extractor: (code) => {
        // 提取 Vue 模板中的类名
        const classes = []
        
        // 提取 class 属性
        const classMatches = code.match(/class=["']([^"']*)["']/g)
        if (classMatches) {
          classMatches.forEach(match => {
            const classNames = match.match(/class=["']([^"']*)["']/)[1]
            classes.push(...classNames.split(/\s+/))
          })
        }
        
        // 提取属性化模式
        const attrMatches = code.match(/\s(\w+)=["']([^"']*)["']/g)
        if (attrMatches) {
          attrMatches.forEach(match => {
            const [, attr, value] = match.match(/\s(\w+)=["']([^"']*)["']/)
            if (['bg', 'text', 'border', 'p', 'm'].includes(attr)) {
              classes.push(...value.split(/\s+/).map(v => `${attr}-${v}`))
            }
          })
        }
        
        return classes
      },
      extensions: ['vue'],
    },
  ],
})

2. React 项目配置

// uno.config.js
import { defineConfig, presetUno } from 'unocss'

export default defineConfig({
  presets: [
    presetUno(),
  ],
  
  // React 特定配置
  extractors: [
    {
      extractor: (code) => {
        // 提取 JSX 中的类名
        const classes = []
        
        // className 属性
        const classNameMatches = code.match(/className=["']([^"']*)["']/g)
        if (classNameMatches) {
          classNameMatches.forEach(match => {
            const classNames = match.match(/className=["']([^"']*)["']/)[1]
            classes.push(...classNames.split(/\s+/))
          })
        }
        
        // 模板字符串中的类名
        const templateMatches = code.match(/`[^`]*`/g)
        if (templateMatches) {
          templateMatches.forEach(match => {
            const content = match.slice(1, -1)
            const possibleClasses = content.match(/[\w-:]+/g) || []
            classes.push(...possibleClasses)
          })
        }
        
        return classes
      },
      extensions: ['jsx', 'tsx'],
    },
  ],
})

3. Svelte 项目配置

// uno.config.js
import { defineConfig, presetUno } from 'unocss'
import { extractorSvelte } from '@unocss/core'

export default defineConfig({
  presets: [
    presetUno(),
  ],
  
  extractors: [
    extractorSvelte(),
  ],
})

IDE 支持和插件

1. VS Code 配置

安装扩展

// .vscode/extensions.json
{
  "recommendations": [
    "antfu.unocss",
    "bradlc.vscode-tailwindcss"
  ]
}

工作区配置

// .vscode/settings.json
{
  "unocss.root": "./",
  "unocss.configFile": "uno.config.ts",
  
  // 自动补全
  "editor.quickSuggestions": {
    "strings": true
  },
  
  // 文件关联
  "files.associations": {
    "*.css": "postcss"
  },
  
  // CSS 验证
  "css.validate": false,
  "less.validate": false,
  "scss.validate": false,
  
  // Emmet 支持
  "emmet.includeLanguages": {
    "javascript": "javascriptreact",
    "typescript": "typescriptreact"
  }
}

2. WebStorm/IntelliJ 配置

// 在 WebStorm 中启用 UnoCSS 支持
// Settings > Languages & Frameworks > Style Sheets > Tailwind CSS
// 启用 Tailwind CSS 支持(UnoCSS 兼容)

3. Vim/Neovim 配置

-- init.lua (Neovim)
require('packer').startup(function()
  use 'neovim/nvim-lspconfig'
  use 'hrsh7th/nvim-cmp'
  use 'hrsh7th/cmp-nvim-lsp'
  
  -- UnoCSS 语法高亮
  use 'NvChad/nvim-colorizer.lua'
  
  -- Tailwind CSS 支持(兼容 UnoCSS)
  use 'roobert/tailwindcss-colorizer-cmp.nvim'
end)

-- LSP 配置
local lspconfig = require('lspconfig')

-- CSS LSP
lspconfig.cssls.setup({
  settings = {
    css = {
      validate = true,
      lint = {
        unknownAtRules = "ignore"
      }
    }
  }
})

开发工具

1. UnoCSS Inspector

// vite.config.js
import { defineConfig } from 'vite'
import UnoCSS from 'unocss/vite'

export default defineConfig({
  plugins: [
    UnoCSS({
      // 启用检查器
      inspector: true,
    }),
  ],
})

访问 http://localhost:3000/__unocss 查看生成的样式。

2. 命令行工具

# 安装 CLI
npm install -g @unocss/cli

# 生成 CSS
unocss "src/**/*.{html,js,ts,jsx,tsx,vue}" -o dist/uno.css

# 监听模式
unocss "src/**/*.{html,js,ts,jsx,tsx,vue}" -o dist/uno.css --watch

# 配置文件
unocss "src/**/*.{html,js,ts,jsx,tsx,vue}" -o dist/uno.css -c uno.config.js

# 压缩输出
unocss "src/**/*.{html,js,ts,jsx,tsx,vue}" -o dist/uno.css --minify

3. 浏览器开发工具

// 开发环境调试
if (process.env.NODE_ENV === 'development') {
  // 启用运行时检查
  window.__unocss_runtime = {
    debug: true,
    inspector: true,
  }
}

环境变量配置

1. 开发环境

# .env.development
UNOCSS_DEBUG=true
UNOCSS_INSPECTOR=true
UNOCSS_HMR=true

2. 生产环境

# .env.production
UNOCSS_MINIFY=true
UNOCSS_EXTRACT=true
UNOCSS_PURGE=true

3. 配置文件中使用环境变量

// uno.config.js
import { defineConfig } from 'unocss'

const isDev = process.env.NODE_ENV === 'development'
const isProd = process.env.NODE_ENV === 'production'

export default defineConfig({
  // 开发环境配置
  ...(isDev && {
    inspector: true,
    hmr: true,
  }),
  
  // 生产环境配置
  ...(isProd && {
    minify: true,
    extract: true,
  }),
  
  // 根据环境变量调整规则
  rules: [
    // 开发环境添加调试规则
    ...(isDev ? [
      ['debug-red', { 'background-color': 'red', 'color': 'white' }],
      ['debug-green', { 'background-color': 'green', 'color': 'white' }],
    ] : []),
    
    // 通用规则
    [/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
  ],
})

故障排除

1. 常见问题

样式不生效

// 检查配置文件
// 1. 确保正确导入 UnoCSS
import 'virtual:uno.css'

// 2. 检查内容配置
export default defineConfig({
  content: {
    filesystem: [
      'src/**/*.{html,js,ts,jsx,tsx,vue,svelte}',
    ],
  },
})

// 3. 检查提取器
extractors: [
  {
    extractor: (code) => {
      console.log('Extracting from:', code.slice(0, 100))
      return code.match(/[\w-:]+/g) || []
    },
    extensions: ['html', 'js', 'ts', 'jsx', 'tsx', 'vue'],
  },
],

构建错误

// 检查依赖版本
// package.json
{
  "devDependencies": {
    "unocss": "^0.58.0",
    "@unocss/vite": "^0.58.0",
    "vite": "^5.0.0"
  }
}

// 清除缓存
// rm -rf node_modules/.cache
// rm -rf .vite
// npm install

性能问题

// 优化配置
export default defineConfig({
  // 限制扫描范围
  content: {
    filesystem: [
      'src/**/*.{vue,js,ts}',
      '!src/**/*.d.ts',
      '!src/**/*.spec.ts',
    ],
  },
  
  // 使用缓存
  cache: {
    enabled: true,
    dir: '.unocss-cache',
  },
  
  // 优化规则
  rules: [
    // 避免过于复杂的正则表达式
    [/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
  ],
})

2. 调试技巧

// 启用调试模式
export default defineConfig({
  // 调试配置
  debug: {
    enabled: true,
    logLevel: 'verbose',
  },
  
  // 自定义日志
  rules: [
    [/^debug-(.+)$/, ([, value]) => {
      console.log('Debug rule matched:', value)
      return { 'data-debug': value }
    }],
  ],
})

本章总结

通过本章学习,我们掌握了:

  1. 安装方式:npm、yarn、pnpm 和 CDN 安装
  2. 配置文件:完整的配置选项和最佳实践
  3. 构建工具集成:Vite、Webpack、PostCSS 等集成方法
  4. 框架支持:Vue、React、Svelte 等框架的特定配置
  5. IDE 支持:VS Code、WebStorm、Vim 等编辑器的配置
  6. 开发工具:Inspector、CLI、浏览器工具等
  7. 故障排除:常见问题的解决方案

核心要点

  • UnoCSS 支持多种安装和集成方式
  • 配置文件提供了极大的灵活性
  • 良好的 IDE 支持提升开发体验
  • 丰富的调试工具帮助解决问题

下一步

在下一章中,我们将深入学习 UnoCSS 的预设系统和规则引擎,了解如何使用和创建预设。

练习题

  1. 环境搭建:在一个新的 Vite + Vue 项目中配置 UnoCSS
  2. 配置优化:为一个大型项目优化 UnoCSS 配置以提升构建性能
  3. 自定义提取器:编写一个自定义提取器来处理特殊的类名格式
  4. 多框架支持:配置 UnoCSS 同时支持 Vue 和 React 组件
  5. 调试实践:使用 UnoCSS Inspector 调试样式生成问题