Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vite: Don't track candidate changes for Svelte <style> tags #14981

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Support opacity values in increments of `0.25` by default ([#14980](https://github.com/tailwindlabs/tailwindcss/pull/14980))

### Fixed

- Ensure that CSS inside Svelte `<style>` blocks always run the expected Svelte processors when using the Vite extension ([#14981](https://github.com/tailwindlabs/tailwindcss/pull/14981))

## [4.0.0-alpha.33] - 2024-11-11

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion integrations/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ interface TestContext {
dumpFiles(pattern: string): Promise<string>
expectFileToContain(
filePath: string,
contents: string | string[] | RegExp | RegExp[],
contents: string | RegExp | (string | RegExp)[],
): Promise<void>
expectFileNotToContain(filePath: string, contents: string | string[]): Promise<void>
}
Expand Down
127 changes: 102 additions & 25 deletions integrations/vite/svelte.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,50 @@ test(
target: document.body,
})
`,
'src/index.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
`,
'src/App.svelte': html`
<script>
import './index.css'
let name = 'world'
</script>

<h1 class="foo underline">Hello {name}!</h1>
<h1 class="global local underline">Hello {name}!</h1>

<style global>
@import 'tailwindcss/utilities';
<style>
@import 'tailwindcss/theme' theme(reference);
@import './components.css';
@import './other.css';
</style>
`,
'src/components.css': css`
.foo {
'src/other.css': css`
.local {
@apply text-red-500;
animation: 2s ease-in-out 0s infinite localKeyframes;
}

:global(.global) {
@apply text-green-500;
animation: 2s ease-in-out 0s infinite globalKeyframes;
}

@keyframes -global-globalKeyframes {
0% {
opacity: 0;
}
100% {
opacity: 100%;
}
}

@keyframes localKeyframes {
0% {
opacity: 0;
}
100% {
opacity: 100%;
}
}
`,
},
Expand All @@ -74,7 +102,13 @@ test(
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)

await fs.expectFileToContain(files[0][0], [candidate`underline`, candidate`foo`])
await fs.expectFileToContain(files[0][0], [
candidate`underline`,
'.global{color:var(--color-green-500);animation:2s ease-in-out 0s infinite globalKeyframes}',
/\.local.svelte-.*\{color:var\(--color-red-500\);animation:2s ease-in-out 0s infinite svelte-.*-localKeyframes\}/,
/@keyframes globalKeyframes\{/,
/@keyframes svelte-.*-localKeyframes\{/,
])
},
)

Expand Down Expand Up @@ -127,51 +161,94 @@ test(
`,
'src/App.svelte': html`
<script>
import './index.css'
let name = 'world'
</script>

<h1 class="foo underline">Hello {name}!</h1>
<h1 class="local global underline">Hello {name}!</h1>

<style global>
@import 'tailwindcss/utilities';
<style>
@import 'tailwindcss/theme' theme(reference);
@import './components.css';
@import './other.css';
</style>
`,
'src/components.css': css`
.foo {
'src/index.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
`,
'src/other.css': css`
.local {
@apply text-red-500;
animation: 2s ease-in-out 0s infinite localKeyframes;
}

:global(.global) {
@apply text-green-500;
animation: 2s ease-in-out 0s infinite globalKeyframes;
}

@keyframes -global-globalKeyframes {
0% {
opacity: 0;
}
100% {
opacity: 100%;
}
}

@keyframes localKeyframes {
0% {
opacity: 0;
}
100% {
opacity: 100%;
}
}
`,
},
},
async ({ fs, spawn }) => {
await spawn(`pnpm vite build --watch`)

let filename = ''
await retryAssertion(async () => {
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
filename = files[0][0]
let [, css] = files[0]
expect(css).toContain(candidate`underline`)
expect(css).toContain(
'.global{color:var(--color-green-500);animation:2s ease-in-out 0s infinite globalKeyframes}',
)
expect(css).toMatch(
/\.local.svelte-.*\{color:var\(--color-red-500\);animation:2s ease-in-out 0s infinite svelte-.*-localKeyframes\}/,
)
expect(css).toMatch(/@keyframes globalKeyframes\{/)
expect(css).toMatch(/@keyframes svelte-.*-localKeyframes\{/)
})

await fs.expectFileToContain(filename, [candidate`foo`, candidate`underline`])
await fs.write(
'src/App.svelte',
(await fs.read('src/App.svelte')).replace('underline', 'font-bold bar'),
)

await fs.write(
'src/components.css',
css`
.bar {
@apply text-green-500;
}
`,
'src/other.css',
`${await fs.read('src/other.css')}\n.bar { @apply text-pink-500; }`,
)

await retryAssertion(async () => {
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
let [, css] = files[0]
expect(css).toContain(candidate`underline`)
expect(css).toContain(candidate`bar`)
expect(css).not.toContain(candidate`foo`)
expect(css).toContain(candidate`font-bold`)
expect(css).toContain(
'.global{color:var(--color-green-500);animation:2s ease-in-out 0s infinite globalKeyframes}',
)
expect(css).toMatch(
/\.local.svelte-.*\{color:var\(--color-red-500\);animation:2s ease-in-out 0s infinite svelte-.*-localKeyframes\}/,
)
expect(css).toMatch(/@keyframes globalKeyframes\{/)
expect(css).toMatch(/@keyframes svelte-.*-localKeyframes\{/)
expect(css).toMatch(/\.bar.svelte-.*\{color:var\(--color-pink-500\)\}/)
})
},
)
Loading