tailwindcss/integrations/vite/source-maps.test.ts
Robin Malfait 73983e1cf5
Fix 'Sourcemap is likely to be incorrect' warnings when using @tailwindcss/vite (#20103)
This PR fixes an issue where a bunch of warnings would be shown related
to sourcemaps.

This happens when we are dealing with CSS files that are _not_ Tailwind
CSS roots. In that case, in the `transform` step, we return the `src` of
that module as-is because we didn't modify anything. However, when
nothing changed, you have to return a `NullValue` such as `undefined`.

So this is a stupid little fix, but it should get rid of a bunch of
annoying warnings.

Fixes: #19930

## Test plan

- Added an integration test to mimic the problem
- Other tests still pass
- Tested it against the reproduction provided in #19930


Before:
<img width="1887" height="1763" alt="8oQNG5Lqr2B"
src="https://github.com/user-attachments/assets/2d8af456-4176-4f18-92a3-5327e395ac6b"
/>


After:
<img width="1885" height="1404" alt="8oQND5kWSb4"
src="https://github.com/user-attachments/assets/7dd98ea4-126b-45d4-9411-0afbacd2c797"
/>
2026-05-22 17:57:25 +02:00

157 lines
3.9 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: '}...',
})
},
)
// https://github.com/tailwindlabs/tailwindcss/issues/19930
test(
'production build without Tailwind roots should not result in source map warnings',
{
fs: {
'package.json': json`
{
"type": "module",
"dependencies": {
"@tailwindcss/vite": "workspace:^",
"tailwindcss": "workspace:^"
},
"devDependencies": {
"vite": "^7"
}
}
`,
'vite.config.ts': ts`
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
{
name: 'inspect-source-map-chain',
enforce: 'pre',
transform(_, id) {
if (id.includes('.css')) {
// Force Rollup to collapse the sourcemap chain during this build.
this.getCombinedSourcemap()
}
},
},
],
css: {
devSourcemap: true,
},
build: {
sourcemap: true,
},
})
`,
'index.html': html`
<body>
<script type="module" src="./src/index.js"></script>
<div>Hello, world!</div>
</body>
`,
'src/index.js': ts` import './index.css' `,
'src/index.css': css`
body {
color: red;
}
`,
},
},
async ({ exec, expect }) => {
let output = await exec('pnpm vite build')
expect(output).not.toContain('Sourcemap is likely to be incorrect')
},
)