Skip to content

Commit

Permalink
fix(vite): fix asset emit (#1926)
Browse files Browse the repository at this point in the history
* fix(vite): fix asset emit

* chore: rename plugin
  • Loading branch information
sibbng committed Nov 29, 2022
1 parent daba01c commit f48862b
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 12 deletions.
11 changes: 11 additions & 0 deletions examples/vite-vue3/public/uno.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/vite-vue3/src/App.vue
Expand Up @@ -6,5 +6,6 @@
</div>
<div i-custom-icon />
<div i-custom-multi-line-attr />
<div hidden class="bg-[url(../src/uno.svg)] bg-[url(/uno.svg)]" />
</div>
</template>
11 changes: 11 additions & 0 deletions examples/vite-vue3/src/uno.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 49 additions & 12 deletions packages/vite/src/modes/global/build.ts
@@ -1,6 +1,7 @@
import { resolve } from 'path'
import type { Plugin, ResolvedConfig } from 'vite'
import type { GenerateResult, UnocssPluginContext } from '@unocss/core'
import type { PluginContext } from 'rollup'
import {
HASH_PLACEHOLDER_RE, LAYER_MARK_ALL, LAYER_PLACEHOLDER_RE,
RESOLVED_ID_RE,
Expand All @@ -24,14 +25,14 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
const cssPostPlugins = new Map<string | undefined, Plugin | undefined>()
const cssPlugins = new Map<string | undefined, Plugin | undefined>()

async function applyCssTransform(css: string, id: string, dir: string | undefined) {
async function applyCssTransform(css: string, id: string, dir: string | undefined, ctx: PluginContext) {
const {
postcss = true,
} = await getConfig()
if (!cssPlugins.get(dir) || !postcss)
return css
// @ts-expect-error no this context
const result = await cssPlugins.get(dir).transform(css, id)
// @ts-expect-error without this context absolute assets will throw an error
const result = await cssPlugins.get(dir).transform.call(ctx, css, id)
if (!result)
return css
if (typeof result === 'string')
Expand Down Expand Up @@ -122,7 +123,7 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get

let { css } = await generateAll()
const fakeCssId = `${chunk.fileName}-unocss-hash.css`
css = await applyCssTransform(css, fakeCssId, options.dir)
css = await applyCssTransform(css, fakeCssId, options.dir, this)

const hash = getHash(css)
const transformHandler = 'handler' in cssPost.transform!
Expand All @@ -145,6 +146,32 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
{
name: 'unocss:global:build:generate',
apply: 'build',
async renderChunk(code, chunk, options) {
const cssPost = cssPostPlugins.get(options.dir)
if (!cssPost) {
this.warn('[unocss] failed to find vite:css-post plugin. It might be an internal bug of UnoCSS')
return null
}
const result = await generateAll()
const cssWithLayers = Array.from(vfsLayers).map(layer =>
`#--unocss-layer-start--${layer}--{start:${layer}} ${
layer === LAYER_MARK_ALL
? result.getLayers(undefined, Array.from(vfsLayers))
: result.getLayer(layer) || ''
} #--unocss-layer-end--${layer}--{end:${layer}}`,
).join('')

const fakeCssId = `${chunk.fileName}-unocss-hash.css`
const css = await applyCssTransform(cssWithLayers, fakeCssId, options.dir, this)
const transformHandler = 'handler' in cssPost.transform!
? cssPost.transform.handler
: cssPost.transform!
await transformHandler.call({} as unknown as any, css, fakeCssId)
},
},
{
name: 'unocss:global:build:bundle',
apply: 'build',
configResolved(config) {
viteConfig = config
},
Expand All @@ -164,34 +191,44 @@ export function GlobalModeBuildPlugin({ uno, ready, extract, tokens, filter, get
return
}

const result = await generateAll()
let replaced = false
const getLayer = (layer: string, input: string, replace = false) => {
const re = new RegExp(`#--unocss-layer-start--${layer}--\\{start:${layer}\\}([\\s\\S]*?)#--unocss-layer-end--${layer}--\\{end:${layer}\\}`, 'g')
if (replace)
return input.replace(re, '')

const match = re.exec(input)
if (match)
return match[1]
return ''
}

for (const file of files) {
const chunk = bundle[file]

if (chunk.type === 'asset' && typeof chunk.source === 'string') {
const css = chunk.source
.replace(HASH_PLACEHOLDER_RE, '')
chunk.source = await replaceAsync(css, LAYER_PLACEHOLDER_RE, async (_, __, layer) => {
replaced = true
return layer === LAYER_MARK_ALL
? result.getLayers(undefined, Array.from(vfsLayers))
: result.getLayer(layer) || ''
return getLayer(layer, css)
})
Array.from(vfsLayers).forEach((layer) => {
chunk.source = getLayer(layer, chunk.source as string, true)
})
}
else if (chunk.type === 'chunk' && typeof chunk.code === 'string') {
const js = chunk.code
.replace(HASH_PLACEHOLDER_RE, '')
chunk.code = await replaceAsync(js, LAYER_PLACEHOLDER_RE, async (_, __, layer) => {
replaced = true
const css = layer === LAYER_MARK_ALL
? result.getLayers(undefined, Array.from(vfsLayers))
: result.getLayer(layer) || ''
const css = getLayer(layer, js)
return css
.replace(/\n/g, '')
.replace(/(?<!\\)(['"])/g, '\\$1')
})
Array.from(vfsLayers).forEach((layer) => {
chunk.code = getLayer(layer, chunk.code, true)
})
}
}

Expand Down

0 comments on commit f48862b

Please sign in to comment.