Skip to content

Vite 插件

🌐 Vite Plugin

Vite 插件随 unocss 包一起提供。

🌐 The Vite plugin ships with the unocss package.

安装

🌐 Installation

bash
pnpm add -D unocss
bash
yarn add -D unocss
bash
npm install -D unocss
bash
bun add -D unocss

安装插件:

🌐 Install the plugin:

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

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

创建一个 uno.config.ts 文件:

🌐 Create a uno.config.ts file:

uno.config.ts
ts
import { defineConfig } from 'unocss'

export default defineConfig({
  // ...UnoCSS options
})

virtual:uno.css 添加到你的主条目:

🌐 Add virtual:uno.css to your main entry:

main.ts
ts
import 'virtual:uno.css'

模式

🌐 Modes

Vite 插件附带了一组可实现不同行为的模式。

🌐 The Vite plugin comes with a set of modes that enable different behaviors.

global(默认)

🌐 global (default)

这是插件的默认模式:在此模式下,你需要在入口点添加 uno.css 的导入。

🌐 This is the default mode for the plugin: in this mode you need to add the import of uno.css on your entry point.

此模式启用一组针对 build 的 Vite 插件以及支持 HMRdev 插件。

🌐 This mode enables a set of Vite plugins for build and for dev with HMR support.

生成的 css 将是一个全局样式表,注入到 index.html 上。

🌐 The generated css will be a global stylesheet injected on the index.html.

vue-scoped

此模式将向 Vue 单文件组件 <style scoped> 注入生成的 CSS 以实现隔离。

🌐 This mode will inject generated CSS to Vue SFCs <style scoped> for isolation.

svelte-scoped

svelte-scoped 模式已被移至其自己的包,详见 @unocss/svelte-scoped/vite

shadow-dom

由于 Web Components 使用了 Shadow DOM,无法直接从全局样式表对内容进行样式设置(除非你使用 CSS custom properties,它们可以穿透 Shadow DOM),你需要将插件生成的 CSS 内联到 Shadow DOM 样式中。

🌐 Since Web Components uses Shadow DOM, there is no way to style content directly from a global stylesheet (unless you use CSS custom properties, those will penetrate the Shadow DOM), you need to inline the generated CSS by the plugin into the Shadow DOM style.

要将生成的 CSS 内联,只需将插件模式配置为 shadow-dom,并在每个 Web 组件样式 CSS 块中包含 @unocss-placeholder 魔法占位符。如果你在 Vue SFC 中定义 Web 组件,并且希望在 UnoCSS 旁边定义自定义样式,可以将占位符封装在 CSS 注释中,以避免在 IDE 中出现语法错误。

🌐 To inline the generated CSS, you only need to configure the plugin mode to shadow-dom and include @unocss-placeholder magic placeholder on each web component style CSS block. If you are defining your Web Components in Vue SFCs and want to define custom styles alongside UnoCSS, you can wrap placeholder in a CSS comment to avoid syntax errors in your IDE.

per-module(实验性)

🌐 per-module (experimental)

此模式将为每个模块生成一个 CSS 表,可以限定作用域。

🌐 This mode will generate a CSS sheet for each module, can be scoped.

dist-chunk(实验性)

🌐 dist-chunk (experimental)

此模式将为构建时的每个代码块生成一个 CSS 表,非常适合 MPA。

🌐 This mode will generate a CSS sheet for each code chunk on build, great for MPA.

在 DevTools 中编辑类

🌐 Edit classes in DevTools

因为“按需加载”的限制,DevTools 无法知道你在源码中尚未使用的内容。所以如果你想通过直接在 DevTools 中修改类来尝试效果,只需在你的主入口文件中添加以下几行代码。

🌐 Because of limitation of "on-demand" where the DevTools don't know those you haven't used in your source code yet. So if you want to try how things work by directly changing the classes in DevTools, just add the following lines to your main entry.

ts
import 'uno.css'
import 'virtual:unocss-devtools'

WARNING

请谨慎使用,在底层我们使用 MutationObserver 来检测类的变化。这意味着不仅是你的手动更改,还有你脚本所做的更改都会被检测并包含在样式表中。这可能会导致当你在脚本标签中根据某些逻辑添加动态类时,开发环境和生产环境之间出现一些不一致。我们建议将你的动态部分添加到 safelist 中,或者如果可能的话为你的生产环境构建设置 UI 回归测试。

构架

🌐 Frameworks

某些 UI/应用框架有一些警告,必须修复这些警告才能使其正常工作,如果你使用以下框架之一,只需应用建议即可。

🌐 Some UI/App frameworks have some caveats that must be fixed to make it work, if you're using one of the following frameworks, just apply the suggestions.

VanillaJS / TypeScript

在使用 VanillaJS 或 TypeScript 时,你需要添加 jsts 文件扩展名以允许 UnoCSS 读取和解析内容,默认情况下 jsts 文件被排除,查看 从构建工具管道提取 部分。

🌐 When using VanillaJS or TypeScript, you need to add js and ts files extensions to allow UnoCSS read and parse the content, by default js and ts files are excluded, check out the Extracting from Build Tools Pipeline section.

React

如果你正在使用 @vitejs/plugin-react

🌐 If you're using @vitejs/plugin-react:

vite.config.ts
ts
import React from '@vitejs/plugin-react'
import UnoCSS from 'unocss/vite'

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

如果你正在使用 @unocss/preset-attributify,你应该从 build 脚本中移除 tsc

🌐 If you're using @unocss/preset-attributify you should remove tsc from the build script.

如果你正在使用 babel-plugin-react-compiler,或者在 @unocss/preset-attributify 中使用 @vitejs/plugin-react,你必须在 @vitejs/plugin-react 之前添加插件。

🌐 If you are using babel-plugin-react-compiler, or @vitejs/plugin-react with @unocss/preset-attributify, you must add the plugin before @vitejs/plugin-react.

vite.config.ts
ts
import React from '@vitejs/plugin-react'
import UnoCSS from 'unocss/vite'

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

你在 examples/vite-react 目录下有一个 React 示例项目,使用了两个插件,请查看 package.json 上的脚本及其 Vite 配置文件。

🌐 You have a React example project on examples/vite-react directory using both plugins, check the scripts on package.json and its Vite configuration file.

Preact

如果你正在使用 @preact/preset-vite

🌐 If you're using @preact/preset-vite:

vite.config.ts
ts
import Preact from '@preact/preset-vite'
import UnoCSS from 'unocss/vite'

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

或者如果你使用的是 @prefresh/vite

🌐 or if you're using @prefresh/vite:

vite.config.ts
ts
import Prefresh from '@prefresh/vite'
import UnoCSS from 'unocss/vite'

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

如果你正在使用 @unocss/preset-attributify,你应该从 build 脚本中移除 tsc

🌐 If you're using @unocss/preset-attributify you should remove tsc from the build script.

你在 examples/vite-preact 目录下有一个 Preact 示例项目,使用了这两个插件,查看 package.json 上的脚本及其 Vite 配置文件。

🌐 You have a Preact example project on examples/vite-preact directory using both plugins, check the scripts on package.json and its Vite configuration file.

Svelte

你必须在 @sveltejs/vite-plugin-svelte 之前添加插件。

🌐 You must add the plugin before @sveltejs/vite-plugin-svelte.

要支持 class:fooclass:foo={bar},请添加插件并在 extractors 选项中配置 extractorSvelte

🌐 To support class:foo and class:foo={bar} add the plugin and configure extractorSvelte on extractors option.

你可以对 class: 使用简单规则,例如 class:bg-red-500={foo},或者使用 shortcuts 包含多个规则,详见下面链接示例项目中的 src/App.svelte

🌐 You can use simple rules with class:, for example class:bg-red-500={foo} or using shortcuts to include multiples rules, see src/App.svelte on linked example project below.

vite.config.ts
ts
import { svelte } from '@sveltejs/vite-plugin-svelte'
import extractorSvelte from '@unocss/extractor-svelte'
import UnoCSS from 'unocss/vite'

export default {
  plugins: [
    UnoCSS({
      extractors: [
        extractorSvelte(),
      ],
      /* more options */
    }),
    svelte(),
  ],
}

Sveltekit

要支持 class:fooclass:foo={bar},请添加插件并在 extractors 选项中配置 extractorSvelte

🌐 To support class:foo and class:foo={bar} add the plugin and configure extractorSvelte on extractors option.

你可以对 class: 使用简单规则,例如 class:bg-red-500={foo},或者使用 shortcuts 包含多个规则,详见下面链接示例项目中的 src/routes/+layout.svelte

🌐 You can use simple rules with class:, for example class:bg-red-500={foo} or using shortcuts to include multiples rules, see src/routes/+layout.svelte on linked example project below.

vite.config.ts
ts
import { sveltekit } from '@sveltejs/kit/vite'
import extractorSvelte from '@unocss/extractor-svelte'
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    UnoCSS({
      extractors: [
        extractorSvelte(),
      ],
      /* more options */
    }),
    sveltekit(),
  ],
})

Web Components

要使用 Web 组件,你需要在插件上启用 shadow-dom 模式。

🌐 To work with web components you need to enable shadow-dom mode on the plugin.

不要忘记移除 uno.css 的导入,因为 shadow-dom 模式不会暴露它,应用将无法运行。

🌐 Don't forget to remove the import for uno.css since the shadow-dom mode will not expose it and the application will not work.

vite.config.ts
ts
import UnoCSS from 'unocss/vite'

export default {
  plugins: [
    UnoCSS({
      mode: 'shadow-dom',
      /* more options */
    }),
  ],
}

在每个 web component 上,只需将 @unocss-placeholder 添加到其样式 CSS 块中:

🌐 On each web component just add @unocss-placeholder to its style CSS block:

ts
const template = document.createElement('template')
template.innerHTML = `
<style>
:host {...}
@unocss-placeholder
</style>
<div class="m-1em">
...
</div>
`

如果你正在使用 Lit

🌐 If you're using Lit:

ts
@customElement('my-element')
export class MyElement extends LitElement {
  static styles = css`
    :host {...}
    @unocss-placeholder
  `
  // ...
}

你在 examples/vite-lit 目录下有一个 Web Components 示例项目。

🌐 You have a Web Components example project on examples/vite-lit directory.

::part 内置支持

🌐 ::part built-in support

你可以使用 ::part,因为插件通过 shortcuts 支持它,并且可以使用来自 preset-minipart-[<part-name>]:<rule|shortcut> 规则,例如,可以将其与简单规则如 part-[<part-name>]:bg-green-500 一起使用,或者使用一些 shortcut:请查看下方链接示例项目中的 src/my-element.ts

part-[<part-name>]:<rule|shortcut> 只能在使用 shadow-dom 模式时与此插件一起工作。

该插件使用 nth-of-type 来避免同一个 Web 组件中多个部分之间以及不同 Web 组件上相同部分之间的冲突,你无需担心,插件会为你处理好。

🌐 The plugin uses nth-of-type to avoid collisions with multiple parts in the same web component and for the same parts on distinct web components, you don't need to worry about it, the plugin will take care for you.

vite.config.ts
ts
import UnoCSS from 'unocss/vite'

export default {
  plugins: [
    UnoCSS({
      mode: 'shadow-dom',
      shortcuts: [
        { 'cool-blue': 'bg-blue-500 text-white' },
        { 'cool-green': 'bg-green-500 text-black' },
      ],
      /* more options */
    }),
  ],
}

然后在你的 web components 中:

🌐 then in your web components:

ts
// my-container-wc.ts
const template = document.createElement('template')
template.innerHTML = `
<style>
@unocss-placeholder
</style>
<my-wc-with-parts class="part-[cool-part]:cool-blue part-[another-cool-part]:cool-green">...</my-wc-with-parts>
`
ts
// my-wc-with-parts.ts
const template = document.createElement('template')
template.innerHTML = `
<style>
@unocss-placeholder
</style>
<div>
  <div part="cool-part">...</div>
  <div part="another-cool-part">...</div>
</div>
`

Solid

你需要在 UnoCSS 的插件之后添加 vite-plugin-solid 插件。

🌐 You need to add the vite-plugin-solid plugin after UnoCSS's plugin.

vite.config.ts
ts
import UnoCSS from 'unocss/vite'
import solidPlugin from 'vite-plugin-solid'

export default {
  plugins: [
    UnoCSS({
      /* options */
    }),
    solidPlugin(),
  ],
}

Elm

你需要在 UnoCSS 的插件之前添加 vite-plugin-elm 插件。

🌐 You need to add the vite-plugin-elm plugin before UnoCSS's plugin.

vite.config.ts
ts
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vite'
import Elm from 'vite-plugin-elm'

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

Marko

你需要在 UnoCSS 的插件之前添加 @marko/vite@marko/run/vite

🌐 You need to add @marko/vite or @marko/run/vite before UnoCSS's plugin.

vite.config.ts
ts
import marko from '@marko/run/vite'
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vite'

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

旧版

🌐 Legacy

如果 @vitejs/plugin-legacy 配合 renderModernChunks: false 使用,你需要将其添加到 unocss 选项中

🌐 If @vitejs/plugin-legacy with renderModernChunks: false, your need add it to unocss option

ts
import legacy from '@vitejs/plugin-legacy'
import vue from '@vitejs/plugin-vue'
import { presetWind3 } from 'unocss'
import Unocss from 'unocss/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    vue(),
    Unocss({
      presets: [presetWind3()],
      legacy: {
        renderModernChunks: false,
      },
    }),
    legacy({
      targets: ['defaults', 'not IE 11'],
      renderModernChunks: false,
    }),
  ],
})

许可

🌐 License