Skip to content

Commit 375548a

Browse files
authored
feat: add Rollup and Rolldown integration (#5296)
1 parent 25973fd commit 375548a

17 files changed

Lines changed: 518 additions & 13 deletions

File tree

docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const Integrations = [
4343
{ text: 'Astro', link: '/integrations/astro' },
4444
{ text: 'Svelte Scoped', link: '/integrations/svelte-scoped' },
4545
{ text: 'Webpack', link: '/integrations/webpack' },
46+
{ text: 'Rollup and Rolldown', link: '/integrations/rollup' },
4647
{ text: 'Runtime', link: '/integrations/runtime' },
4748
{ text: 'CLI', link: '/integrations/cli' },
4849
{ text: 'PostCSS', link: '/integrations/postcss' },

docs/integrations/rollup.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
title: UnoCSS Rollup and Rolldown Plugin
3+
description: Use UnoCSS with Rollup or Rolldown.
4+
outline: deep
5+
---
6+
7+
# Rollup and Rolldown Plugin
8+
9+
Use UnoCSS with Rollup or Rolldown without Vite. The plugin supports the `global` mode and emits a CSS asset when you import `uno.css` from an entry module.
10+
11+
## Installation
12+
13+
::: code-group
14+
15+
```bash [pnpm]
16+
pnpm add -D unocss rollup
17+
```
18+
19+
```bash [yarn]
20+
yarn add -D unocss rollup
21+
```
22+
23+
```bash [npm]
24+
npm install -D unocss rollup
25+
```
26+
27+
```bash [bun]
28+
bun add -D unocss rollup
29+
```
30+
31+
:::
32+
33+
Replace `rollup` with `rolldown` when you use Rolldown.
34+
35+
## Rollup
36+
37+
```ts [rollup.config.ts]
38+
import UnoCSS from 'unocss/rollup'
39+
40+
export default {
41+
input: 'src/main.ts',
42+
plugins: [
43+
UnoCSS(),
44+
],
45+
}
46+
```
47+
48+
## Rolldown
49+
50+
```ts [rolldown.config.ts]
51+
import UnoCSS from 'unocss/rolldown'
52+
53+
export default {
54+
input: 'src/main.ts',
55+
plugins: [
56+
UnoCSS(),
57+
],
58+
}
59+
```
60+
61+
Import `uno.css` from an entry module:
62+
63+
```ts [src/main.ts]
64+
import 'uno.css'
65+
```
66+
67+
The plugin emits generated CSS as an output asset. Include that asset in your application with your deployment or HTML pipeline.
68+
69+
## Configuration
70+
71+
Create a `uno.config.ts` file:
72+
73+
```ts [uno.config.ts]
74+
import { defineConfig } from 'unocss'
75+
76+
export default defineConfig({
77+
// ...UnoCSS options
78+
})
79+
```
80+
81+
You can also pass the configuration to the plugin directly:
82+
83+
```ts
84+
import UnoCSS from 'unocss/rollup'
85+
86+
UnoCSS({
87+
// ...UnoCSS options
88+
})
89+
```

packages-integrations/README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
Packages that integrate UnoCSS with other tools, they should be aimed for agnostic on presets.
44

5-
| Package | Description | Included in `unocss` |
6-
| ---------------------------------------- | ---------------------------- | -------------------- |
7-
| [@unocss/vite](./vite) | The Vite plugins ||
8-
| [@unocss/astro](./astro) | The Astro integration ||
9-
| [@unocss/webpack](./webpack) | The Webpack plugin | No |
10-
| [@unocss/postcss](./postcss) | The PostCSS plugin | No |
11-
| [@unocss/inspector](./postcss) | Embedded Inspector UI ||
12-
| [@unocss/nuxt](./nuxt) | The Nuxt Module | No |
13-
| [@unocss/runtime](./runtime) | CSS-in-JS Runtime for UnoCSS | No |
14-
| [@unocss/svelte-scoped](./svelte-scoped) | Scoped UnoCSS for Svelte | No |
15-
| [@unocss/eslint-plugin](./eslint-plugin) | ESLint plugin | No |
16-
| [@unocss/eslint-config](./eslint-config) | ESLint config | No |
17-
| [VS Code Extension](./vscode) | UnoCSS for VS Code | - |
5+
| Package | Description | Included in `unocss` |
6+
| ---------------------------------------- | ------------------------------ | -------------------- |
7+
| [@unocss/vite](./vite) | The Vite plugins ||
8+
| [@unocss/astro](./astro) | The Astro integration ||
9+
| [@unocss/webpack](./webpack) | The Webpack plugin | No |
10+
| [@unocss/rollup](./rollup) | The Rollup and Rolldown plugin ||
11+
| [@unocss/postcss](./postcss) | The PostCSS plugin | No |
12+
| [@unocss/inspector](./postcss) | Embedded Inspector UI ||
13+
| [@unocss/nuxt](./nuxt) | The Nuxt Module | No |
14+
| [@unocss/runtime](./runtime) | CSS-in-JS Runtime for UnoCSS | No |
15+
| [@unocss/svelte-scoped](./svelte-scoped) | Scoped UnoCSS for Svelte | No |
16+
| [@unocss/eslint-plugin](./eslint-plugin) | ESLint plugin | No |
17+
| [@unocss/eslint-config](./eslint-config) | ESLint config | No |
18+
| [VS Code Extension](./vscode) | UnoCSS for VS Code | - |
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"name": "@unocss/rollup",
3+
"type": "module",
4+
"version": "66.9.2",
5+
"description": "The Rollup and Rolldown plugin for UnoCSS",
6+
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
7+
"license": "MIT",
8+
"funding": "https://github.com/sponsors/antfu",
9+
"homepage": "https://unocss.dev",
10+
"repository": {
11+
"type": "git",
12+
"url": "git+https://github.com/unocss/unocss.git",
13+
"directory": "packages-integrations/rollup"
14+
},
15+
"bugs": {
16+
"url": "https://github.com/unocss/unocss/issues"
17+
},
18+
"keywords": [
19+
"unocss",
20+
"rollup-plugin",
21+
"rolldown-plugin"
22+
],
23+
"sideEffects": false,
24+
"exports": {
25+
".": "./dist/index.mjs",
26+
"./package.json": "./package.json"
27+
},
28+
"types": "dist/index.d.mts",
29+
"typesVersions": {
30+
"*": {
31+
"*": [
32+
"./dist/*.d.mts",
33+
"./*"
34+
]
35+
}
36+
},
37+
"files": [
38+
"dist"
39+
],
40+
"scripts": {
41+
"build": "tsdown --config-loader unrun",
42+
"prepack": "turbo build --filter=.",
43+
"dev": "tsdown --config-loader unrun --watch"
44+
},
45+
"peerDependencies": {
46+
"rolldown": "^1.0.0",
47+
"rollup": "^4.0.0"
48+
},
49+
"peerDependenciesMeta": {
50+
"rolldown": {
51+
"optional": true
52+
},
53+
"rollup": {
54+
"optional": true
55+
}
56+
},
57+
"dependencies": {
58+
"@jridgewell/remapping": "catalog:build",
59+
"@unocss/config": "workspace:*",
60+
"@unocss/core": "workspace:*",
61+
"chokidar": "catalog:utils",
62+
"magic-string": "catalog:utils",
63+
"pathe": "catalog:utils",
64+
"tinyglobby": "catalog:utils",
65+
"unplugin-utils": "catalog:utils"
66+
},
67+
"devDependencies": {
68+
"rolldown": "catalog:build",
69+
"rollup": "catalog:build"
70+
}
71+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import type { UserConfigDefaults } from '@unocss/core'
2+
import type { RollupPluginConfig, UnoCSSRollupPlugin } from './types'
3+
import process from 'node:process'
4+
import { LAYER_IMPORTS } from '@unocss/core'
5+
import { setupContentExtractor } from '#integration/content'
6+
import { createContext } from '#integration/context'
7+
import { resolveId, resolveLayer } from '#integration/layers'
8+
import { applyTransformers } from '#integration/transformers'
9+
10+
export * from './types'
11+
12+
export function defineConfig<Theme extends object>(config: RollupPluginConfig<Theme>) {
13+
return config
14+
}
15+
16+
export default function RollupPlugin<Theme extends object>(
17+
configOrPath?: RollupPluginConfig<Theme> | string,
18+
defaults: UserConfigDefaults = {},
19+
): UnoCSSRollupPlugin {
20+
const ctx = createContext<RollupPluginConfig>(configOrPath as any, {
21+
envMode: process.env.NODE_ENV === 'development' ? 'dev' : 'build',
22+
...defaults,
23+
})
24+
const { extract, filter, flushTasks, getConfig, tasks, tokens } = ctx
25+
const vfsLayers = new Map<string, string>()
26+
const unocssImporters = new Set<string>()
27+
let lastTokenSize = 0
28+
let css = ''
29+
30+
async function generateCss() {
31+
await flushTasks()
32+
if (lastTokenSize === tokens.size)
33+
return css
34+
35+
const result = await ctx.uno.generate(tokens, { minify: true })
36+
css = result.getLayers(undefined, [LAYER_IMPORTS, ...vfsLayers.keys()])
37+
lastTokenSize = tokens.size
38+
return css
39+
}
40+
41+
return {
42+
name: 'unocss:rollup',
43+
async buildStart() {
44+
await ctx.ready
45+
vfsLayers.clear()
46+
tasks.length = 0
47+
lastTokenSize = 0
48+
css = ''
49+
tasks.push(setupContentExtractor(ctx))
50+
},
51+
async transform(code, id) {
52+
if (!filter(code, id))
53+
return null
54+
55+
const preTransform = await applyTransformers(ctx, code, id, 'pre')
56+
const defaultTransform = await applyTransformers(ctx, preTransform?.code || code, id)
57+
const postTransform = await applyTransformers(ctx, defaultTransform?.code || preTransform?.code || code, id, 'post')
58+
const transformedCode = postTransform?.code || defaultTransform?.code || preTransform?.code || code
59+
60+
tasks.push(extract(transformedCode, id))
61+
return postTransform || defaultTransform || preTransform || null
62+
},
63+
async resolveId(id, importer) {
64+
const entry = await resolveId(ctx, id, importer)
65+
if (!entry)
66+
return
67+
68+
const layer = await resolveLayer(ctx, entry)
69+
if (!layer)
70+
return entry
71+
72+
if (importer)
73+
unocssImporters.add(importer)
74+
75+
if (vfsLayers.has(layer)) {
76+
this.warn(`[unocss] ${JSON.stringify(id)} is being imported multiple times in different files, using the first occurrence: ${JSON.stringify(vfsLayers.get(layer))}`)
77+
return vfsLayers.get(layer)
78+
}
79+
80+
const virtualEntry = `\0unocss:${layer}`
81+
vfsLayers.set(layer, virtualEntry)
82+
return virtualEntry
83+
},
84+
load(id) {
85+
const layer = Array.from(vfsLayers).find(([, entry]) => entry === id)?.[0]
86+
if (!layer)
87+
return
88+
89+
return {
90+
code: '',
91+
map: null,
92+
moduleSideEffects: true,
93+
}
94+
},
95+
shouldTransformCachedModule({ id }) {
96+
return unocssImporters.delete(id)
97+
},
98+
async generateBundle() {
99+
if (!vfsLayers.size) {
100+
if ((await getConfig()).checkImport) {
101+
this.warn('[unocss] Entry module not found. Did you add `import \'uno.css\'` in your main entry?')
102+
}
103+
return
104+
}
105+
106+
this.emitFile({
107+
type: 'asset',
108+
name: 'uno.css',
109+
source: await generateCss(),
110+
})
111+
},
112+
}
113+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { UserConfig } from '@unocss/core'
2+
import type { Plugin } from 'rollup'
3+
4+
export interface RollupPluginConfig<Theme extends object = object> extends UserConfig<Theme> {
5+
/**
6+
* Warn when no UnoCSS virtual CSS entry is imported.
7+
*
8+
* @default false
9+
*/
10+
checkImport?: boolean
11+
}
12+
13+
export type UnoCSSRollupPlugin = Plugin
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { defineConfig } from 'tsdown'
2+
import { aliasVirtual } from '../../alias'
3+
4+
export default defineConfig({
5+
entry: ['src/index.ts'],
6+
clean: true,
7+
dts: true,
8+
alias: aliasVirtual,
9+
deps: {
10+
neverBundle: [
11+
'rolldown',
12+
'rollup',
13+
],
14+
},
15+
exports: true,
16+
failOnWarn: true,
17+
publint: 'ci-only',
18+
attw: {
19+
enabled: 'ci-only',
20+
ignoreRules: ['cjs-resolves-to-esm'],
21+
},
22+
})

packages-presets/unocss/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
"./preset-wind": "./dist/preset-wind.mjs",
4545
"./preset-wind3": "./dist/preset-wind3.mjs",
4646
"./preset-wind4": "./dist/preset-wind4.mjs",
47+
"./rolldown": "./dist/rolldown.mjs",
48+
"./rollup": "./dist/rollup.mjs",
4749
"./vite": "./dist/vite.mjs",
4850
"./webpack": {
4951
"import": "./dist/webpack.mjs",
@@ -100,6 +102,7 @@
100102
"@unocss/preset-wind": "workspace:*",
101103
"@unocss/preset-wind3": "workspace:*",
102104
"@unocss/preset-wind4": "workspace:*",
105+
"@unocss/rollup": "workspace:*",
103106
"@unocss/transformer-attributify-jsx": "workspace:*",
104107
"@unocss/transformer-compile-class": "workspace:*",
105108
"@unocss/transformer-directives": "workspace:*",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './rollup'
2+
export { default } from './rollup'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { RollupPluginConfig } from '@unocss/rollup'
2+
import type { Plugin } from 'rollup'
3+
import presetWind3 from '@unocss/preset-wind3'
4+
import RollupPlugin from '@unocss/rollup'
5+
6+
export * from '@unocss/rollup'
7+
8+
export default function UnocssRollupPlugin<Theme extends object>(
9+
configOrPath?: RollupPluginConfig<Theme> | string,
10+
): Plugin {
11+
return RollupPlugin(
12+
configOrPath,
13+
{
14+
presets: [
15+
presetWind3(),
16+
],
17+
},
18+
)
19+
}

0 commit comments

Comments
 (0)
Sponsor
SponsoredKunjungi sekarang
Promo