mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Closes #18381 * [Changelog for Vite 7.0.0 (2025-06-24)](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md#700-2025-06-24) Starting from Vite 7, Node 18 support will be dropped, which doesn't really affect Tailwind. It might be worth mentioning in the documentation that the recommended minimum Node versions are 20.19 and 22.12. Vite 7 is only available in ESM format, which is also not an issue. Vite's browser support aligns with the v4 guidelines: ``` Chrome 87 → 107 (tw: 111) Edge 88 → 107 (tw: 111) Firefox 78 → 104 (tw: 128) Safari 14.0 → 16.0 (tw: 16.4) ``` * [Vite 7 - Browser Support](https://vite.dev/guide/migration.html#default-browser-target-change) * [Tailwind CSS v4 - Browser Support](https://tailwindcss.com/docs/compatibility#browser-support) So, at first glance, there's nothing more to do except enabling support for these versions. --------- Co-authored-by: Jordan Pittman <jordan@cryptica.me>
179 lines
4.5 KiB
TypeScript
179 lines
4.5 KiB
TypeScript
import dedent from 'dedent'
|
|
import { describe } from 'vitest'
|
|
import { css, fetchStyles, html, retryAssertion, test, ts, txt } from '../utils'
|
|
|
|
function createSetup(transformer: 'postcss' | 'lightningcss') {
|
|
return {
|
|
fs: {
|
|
'package.json': txt`
|
|
{
|
|
"type": "module",
|
|
"dependencies": {
|
|
"@tailwindcss/vite": "workspace:^",
|
|
"tailwindcss": "workspace:^"
|
|
},
|
|
"devDependencies": {
|
|
${transformer === 'lightningcss' ? `"lightningcss": "^1",` : ''}
|
|
"vite": "^7"
|
|
}
|
|
}
|
|
`,
|
|
'vite.config.ts': ts`
|
|
import tailwindcss from '@tailwindcss/vite'
|
|
import { defineConfig } from 'vite'
|
|
|
|
export default defineConfig({
|
|
css: ${transformer === 'postcss' ? '{}' : "{ transformer: 'lightningcss' }"},
|
|
build: { cssMinify: false },
|
|
plugins: [
|
|
tailwindcss(),
|
|
{
|
|
name: 'recolor',
|
|
transform(code, id) {
|
|
if (id.includes('.css')) {
|
|
return code.replace(/red;/g, 'blue;')
|
|
}
|
|
},
|
|
},
|
|
],
|
|
})
|
|
`,
|
|
'index.html': html`
|
|
<head>
|
|
<link rel="stylesheet" href="./src/index.css" />
|
|
</head>
|
|
<body>
|
|
<div class="foo [background-color:red]">Hello, world!</div>
|
|
</body>
|
|
`,
|
|
'src/index.css': css`
|
|
@reference 'tailwindcss/theme';
|
|
@import 'tailwindcss/utilities';
|
|
|
|
.foo {
|
|
color: red;
|
|
}
|
|
`,
|
|
},
|
|
}
|
|
}
|
|
|
|
describe.each(['postcss', 'lightningcss'] as const)('%s', (transformer) => {
|
|
test(`production build`, createSetup(transformer), async ({ fs, exec, expect }) => {
|
|
await exec('pnpm vite build')
|
|
|
|
let files = await fs.glob('dist/**/*.css')
|
|
expect(files).toHaveLength(1)
|
|
let [filename] = files[0]
|
|
|
|
await fs.expectFileToContain(filename, [
|
|
css`
|
|
.foo {
|
|
color: blue;
|
|
}
|
|
`,
|
|
// Running the transforms on utilities generated by Tailwind might change in the future
|
|
dedent`
|
|
.\[background-color\:red\] {
|
|
background-color: blue;
|
|
}
|
|
`,
|
|
])
|
|
})
|
|
|
|
test('dev mode', createSetup(transformer), async ({ spawn, fs, expect }) => {
|
|
let process = await spawn('pnpm vite dev')
|
|
await process.onStdout((m) => m.includes('ready in'))
|
|
|
|
let url = ''
|
|
await process.onStdout((m) => {
|
|
let match = /Local:\s*(http.*)\//.exec(m)
|
|
if (match) url = match[1]
|
|
return Boolean(url)
|
|
})
|
|
|
|
await retryAssertion(async () => {
|
|
let styles = await fetchStyles(url, '/index.html')
|
|
expect(styles).toContain(css`
|
|
.foo {
|
|
color: blue;
|
|
}
|
|
`)
|
|
// Running the transforms on utilities generated by Tailwind might change in the future
|
|
expect(styles).toContain(dedent`
|
|
.\[background-color\:red\] {
|
|
background-color: blue;
|
|
}
|
|
`)
|
|
})
|
|
|
|
await retryAssertion(async () => {
|
|
await fs.write(
|
|
'src/index.css',
|
|
css`
|
|
@reference 'tailwindcss/theme';
|
|
@import 'tailwindcss/utilities';
|
|
|
|
.foo {
|
|
background-color: red;
|
|
}
|
|
`,
|
|
)
|
|
|
|
let styles = await fetchStyles(url)
|
|
expect(styles).toContain(css`
|
|
.foo {
|
|
background-color: blue;
|
|
}
|
|
`)
|
|
})
|
|
})
|
|
|
|
test('watch mode', createSetup(transformer), async ({ spawn, fs, expect }) => {
|
|
let process = await spawn('pnpm vite build --watch')
|
|
await process.onStdout((m) => m.includes('built in'))
|
|
|
|
await retryAssertion(async () => {
|
|
let files = await fs.glob('dist/**/*.css')
|
|
expect(files).toHaveLength(1)
|
|
let [, styles] = files[0]
|
|
|
|
expect(styles).toContain(css`
|
|
.foo {
|
|
color: blue;
|
|
}
|
|
`)
|
|
// Running the transforms on utilities generated by Tailwind might change in the future
|
|
expect(styles).toContain(dedent`
|
|
.\[background-color\:red\] {
|
|
background-color: blue;
|
|
}
|
|
`)
|
|
})
|
|
|
|
await retryAssertion(async () => {
|
|
await fs.write(
|
|
'src/index.css',
|
|
css`
|
|
@reference 'tailwindcss/theme';
|
|
@import 'tailwindcss/utilities';
|
|
|
|
.foo {
|
|
background-color: red;
|
|
}
|
|
`,
|
|
)
|
|
|
|
let files = await fs.glob('dist/**/*.css')
|
|
expect(files).toHaveLength(1)
|
|
let [, styles] = files[0]
|
|
|
|
expect(styles).toContain(css`
|
|
.foo {
|
|
background-color: blue;
|
|
}
|
|
`)
|
|
})
|
|
})
|
|
})
|