tailwindcss/integrations/vite/source-maps.test.ts
Rózsa Zoltán aa859314d9
feat: add Vite 7 support to the @tailwindcss/vite plugin (#18384)
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>
2025-06-24 12:31:17 -04:00

94 lines
2.3 KiB
TypeScript

import { candidate, css, fetchStyles, html, json, retryAssertion, test, ts } from '../utils'
test(
`dev build`,
{
fs: {
'package.json': json`
{
"type": "module",
"dependencies": {
"@tailwindcss/vite": "workspace:^",
"tailwindcss": "workspace:^"
},
"devDependencies": {
"lightningcss": "^1",
"vite": "^7"
}
}
`,
'vite.config.ts': ts`
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [tailwindcss()],
css: {
devSourcemap: true,
},
})
`,
'index.html': html`
<head>
<link rel="stylesheet" href="./src/index.css" />
</head>
<body>
<div class="flex">Hello, world!</div>
</body>
`,
'src/index.css': css`
@import 'tailwindcss/utilities';
/* */
`,
},
},
async ({ fs, spawn, expect, parseSourceMap }) => {
// Source maps only work in development mode in Vite
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)
})
let styles = await retryAssertion(async () => {
let styles = await fetchStyles(url, '/index.html')
// Wait until we have the right CSS
expect(styles).toContain(candidate`flex`)
return styles
})
// Make sure we can find a source map
let map = parseSourceMap(styles)
expect(map.at(1, 0)).toMatchObject({
source: null,
original: '(none)',
generated: '/*! tailwi...',
})
expect(map.at(2, 0)).toMatchObject({
source: expect.stringContaining('utilities.css'),
original: '@tailwind...',
generated: '.flex {...',
})
expect(map.at(3, 2)).toMatchObject({
source: expect.stringContaining('utilities.css'),
original: '@tailwind...',
generated: 'display: f...',
})
expect(map.at(4, 0)).toMatchObject({
source: null,
original: '(none)',
generated: '}...',
})
},
)