Skip to content

Commit

Permalink
fix(transformer-compile-class): only throw when user explicit name co…
Browse files Browse the repository at this point in the history
…nflicts, close #2667, close #2664
  • Loading branch information
antfu committed May 31, 2023
1 parent 089622a commit c54f3ee
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
24 changes: 15 additions & 9 deletions packages/transformer-compile-class/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface CompileClassOptions {
* This parameter is backwards compatible. It accepts string only trigger
* words, like `:uno:` or a regex literal.
*
* @default `/(["'`]):uno:\s([^\1]*?)\1/g`
* @default `/(["'`]):uno(?:-)?(?<name>[^\s\1]+)?:\s([^\1]*?)\1/g`
*/
trigger?: string | RegExp

Expand Down Expand Up @@ -59,7 +59,7 @@ export interface CompileClassOptions {

export default function transformerCompileClass(options: CompileClassOptions = {}): SourceCodeTransformer {
const {
trigger = /(["'`]):uno:\s([^\1]*?)\1/g,
trigger = /(["'`]):uno(?:-)?(?<name>[^\s\1]+)?:\s([^\1]*?)\1/g,
classPrefix = 'uno-',
hashFn = hash,
keepUnknown = true,
Expand Down Expand Up @@ -97,13 +97,19 @@ export default function transformerCompileClass(options: CompileClassOptions = {

if (body) {
body = body.split(/\s+/).sort().join(' ')
const className = (match.groups && match.groups.name)
? `${classPrefix}${match.groups.name}`
: `${classPrefix}${hashFn(body)}`

// FIXME: Ideally we should also check that the hash doesn't match. If the hash is the same, the same class
// name is allowed, as the applied styles are the same.
if (tokens && tokens.has(className))
let hash: string
let explicitName = false

if (match.groups && match.groups.name) {
hash = match.groups.name
explicitName = true
}
else {
hash = hashFn(body)
}
const className = `${classPrefix}${hash}`

if (tokens && tokens.has(className) && explicitName)
throw new Error(`duplicate compile class name '${className}', please choose different class name`)

replacements.unshift(className)
Expand Down
24 changes: 24 additions & 0 deletions test/transformer-compile-class.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,28 @@ describe('transformer-compile-class', () => {
.uno-foo_bar-baz{--un-bg-opacity:1;background-color:rgba(239,68,68,var(--un-bg-opacity));font-size:1.25rem;line-height:1.75rem;}"
`)
})

test('custom class name conflicts', async () => {
await expect(async () => {
await transform(`
<div class=":uno-foo: w-1"/>
<div class=":uno-foo: w-2"/>
`.trim(), uno)
}).rejects
.toMatchInlineSnapshot('[Error: duplicate compile class name \'uno-foo\', please choose different class name]')
})

test('normal class name should not conflicts', async () => {
const result = await transform(`
<div class=":uno: w-1 h-1"/>
<div class=":uno: w-2 h-2"/>
<div class=":uno: h-1 w-1"/>
`, uno)

expect(result.code.trim()).toMatchInlineSnapshot(`
"<div class=\\"uno-prhvrm\\"/>
<div class=\\"uno-umiu5u\\"/>
<div class=\\"uno-prhvrm\\"/>"
`)
})
})

1 comment on commit c54f3ee

@nguyentuevuong
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still encountering the same old errors after updating to the latest version. The issue lies in the fact that when the vite server restarts, the tokens are not reset, causing the explicit check code to malfunction.

image

UnoCSS version 0.52.6
image

Please sign in to comment.