1
1
import { resolve } from 'path'
2
2
import type { Plugin , ResolvedConfig } from 'vite'
3
3
import type { GenerateResult , UnocssPluginContext } from '@unocss/core'
4
+ import type { PluginContext } from 'rollup'
4
5
import {
5
6
HASH_PLACEHOLDER_RE , LAYER_MARK_ALL , LAYER_PLACEHOLDER_RE ,
6
7
RESOLVED_ID_RE ,
@@ -24,14 +25,14 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
24
25
const cssPostPlugins = new Map < string | undefined , Plugin | undefined > ( )
25
26
const cssPlugins = new Map < string | undefined , Plugin | undefined > ( )
26
27
27
- async function applyCssTransform ( css : string , id : string , dir : string | undefined ) {
28
+ async function applyCssTransform ( css : string , id : string , dir : string | undefined , ctx : PluginContext ) {
28
29
const {
29
30
postcss = true ,
30
31
} = await getConfig ( )
31
32
if ( ! cssPlugins . get ( dir ) || ! postcss )
32
33
return css
33
- // @ts -expect-error no this context
34
- const result = await cssPlugins . get ( dir ) . transform ( css , id )
34
+ // @ts -expect-error without this context absolute assets will throw an error
35
+ const result = await cssPlugins . get ( dir ) . transform . call ( ctx , css , id )
35
36
if ( ! result )
36
37
return css
37
38
if ( typeof result === 'string' )
@@ -122,7 +123,7 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
122
123
123
124
let { css } = await generateAll ( )
124
125
const fakeCssId = `${ chunk . fileName } -unocss-hash.css`
125
- css = await applyCssTransform ( css , fakeCssId , options . dir )
126
+ css = await applyCssTransform ( css , fakeCssId , options . dir , this )
126
127
127
128
const hash = getHash ( css )
128
129
const transformHandler = 'handler' in cssPost . transform !
@@ -145,6 +146,32 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
145
146
{
146
147
name : 'unocss:global:build:generate' ,
147
148
apply : 'build' ,
149
+ async renderChunk ( code , chunk , options ) {
150
+ const cssPost = cssPostPlugins . get ( options . dir )
151
+ if ( ! cssPost ) {
152
+ this . warn ( '[unocss] failed to find vite:css-post plugin. It might be an internal bug of UnoCSS' )
153
+ return null
154
+ }
155
+ const result = await generateAll ( )
156
+ const cssWithLayers = Array . from ( vfsLayers ) . map ( layer =>
157
+ `#--unocss-layer-start--${ layer } --{start:${ layer } } ${
158
+ layer === LAYER_MARK_ALL
159
+ ? result . getLayers ( undefined , Array . from ( vfsLayers ) )
160
+ : result . getLayer ( layer ) || ''
161
+ } #--unocss-layer-end--${ layer } --{end:${ layer } }`,
162
+ ) . join ( '' )
163
+
164
+ const fakeCssId = `${ chunk . fileName } -unocss-hash.css`
165
+ const css = await applyCssTransform ( cssWithLayers , fakeCssId , options . dir , this )
166
+ const transformHandler = 'handler' in cssPost . transform !
167
+ ? cssPost . transform . handler
168
+ : cssPost . transform !
169
+ await transformHandler . call ( { } as unknown as any , css , fakeCssId )
170
+ } ,
171
+ } ,
172
+ {
173
+ name : 'unocss:global:build:bundle' ,
174
+ apply : 'build' ,
148
175
configResolved ( config ) {
149
176
viteConfig = config
150
177
} ,
@@ -164,34 +191,44 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
164
191
return
165
192
}
166
193
167
- const result = await generateAll ( )
168
194
let replaced = false
195
+ const getLayer = ( layer : string , input : string , replace = false ) => {
196
+ const re = new RegExp ( `#--unocss-layer-start--${ layer } --\\{start:${ layer } \\}([\\s\\S]*?)#--unocss-layer-end--${ layer } --\\{end:${ layer } \\}` , 'g' )
197
+ if ( replace )
198
+ return input . replace ( re , '' )
199
+
200
+ const match = re . exec ( input )
201
+ if ( match )
202
+ return match [ 1 ]
203
+ return ''
204
+ }
169
205
170
206
for ( const file of files ) {
171
207
const chunk = bundle [ file ]
172
-
173
208
if ( chunk . type === 'asset' && typeof chunk . source === 'string' ) {
174
209
const css = chunk . source
175
210
. replace ( HASH_PLACEHOLDER_RE , '' )
176
211
chunk . source = await replaceAsync ( css , LAYER_PLACEHOLDER_RE , async ( _ , __ , layer ) => {
177
212
replaced = true
178
- return layer === LAYER_MARK_ALL
179
- ? result . getLayers ( undefined , Array . from ( vfsLayers ) )
180
- : result . getLayer ( layer ) || ''
213
+ return getLayer ( layer , css )
214
+ } )
215
+ Array . from ( vfsLayers ) . forEach ( ( layer ) => {
216
+ chunk . source = getLayer ( layer , chunk . source as string , true )
181
217
} )
182
218
}
183
219
else if ( chunk . type === 'chunk' && typeof chunk . code === 'string' ) {
184
220
const js = chunk . code
185
221
. replace ( HASH_PLACEHOLDER_RE , '' )
186
222
chunk . code = await replaceAsync ( js , LAYER_PLACEHOLDER_RE , async ( _ , __ , layer ) => {
187
223
replaced = true
188
- const css = layer === LAYER_MARK_ALL
189
- ? result . getLayers ( undefined , Array . from ( vfsLayers ) )
190
- : result . getLayer ( layer ) || ''
224
+ const css = getLayer ( layer , js )
191
225
return css
192
226
. replace ( / \n / g, '' )
193
227
. replace ( / (?< ! \\ ) ( [ ' " ] ) / g, '\\$1' )
194
228
} )
229
+ Array . from ( vfsLayers ) . forEach ( ( layer ) => {
230
+ chunk . code = getLayer ( layer , chunk . code , true )
231
+ } )
195
232
}
196
233
}
197
234
0 commit comments