Add source map support to Vite

This commit is contained in:
Jordan Pittman 2025-04-29 19:16:49 -04:00
parent 2f25e3ec3a
commit bb78c59770
2 changed files with 117 additions and 1 deletions

View file

@ -0,0 +1,96 @@
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.26.0",
"vite": "^6"
}
}
`,
'vite.config.ts': ts`
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [tailwindcss()],
css: {
devSourcemap: true,
},
build: {
sourcemap: 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('node_modules/tailwindcss/utilities.css'),
original: '@tailwind...',
generated: '.flex {...',
})
expect(map.at(3, 2)).toMatchObject({
source: expect.stringContaining('node_modules/tailwindcss/utilities.css'),
original: '@tailwind...',
generated: 'display: f...',
})
expect(map.at(4, 0)).toMatchObject({
source: null,
original: '(none)',
generated: '}...',
})
},
)

View file

@ -1,4 +1,12 @@
import { compile, env, Features, Instrumentation, normalizePath, optimize } from '@tailwindcss/node'
import {
compile,
env,
Features,
Instrumentation,
normalizePath,
optimize,
toSourceMap,
} from '@tailwindcss/node'
import { clearRequireCache } from '@tailwindcss/node/require-cache'
import { Scanner } from '@tailwindcss/oxide'
import fs from 'node:fs/promises'
@ -37,6 +45,9 @@ export default function tailwindcss(): Plugin[] {
return new Root(
id,
config!.root,
// Currently, Vite only supports CSS source maps in development and they
// are off by default. Check to see if we need them or not.
config?.css.devSourcemap ?? false,
customCssResolver,
customJsResolver,
)
@ -108,6 +119,7 @@ export default function tailwindcss(): Plugin[] {
DEBUG && I.start('[@tailwindcss/vite] Optimize CSS')
result = optimize(result.code, {
minify,
map: result.map,
})
DEBUG && I.end('[@tailwindcss/vite] Optimize CSS')
@ -180,6 +192,7 @@ class Root {
private id: string,
private base: string,
private enableSourceMaps: boolean,
private customCssResolver: (id: string, base: string) => Promise<string | false | undefined>,
private customJsResolver: (id: string, base: string) => Promise<string | false | undefined>,
) {}
@ -193,6 +206,7 @@ class Root {
): Promise<
| {
code: string
map: string | undefined
}
| false
> {
@ -227,6 +241,7 @@ class Root {
DEBUG && I.start('Setup compiler')
let addBuildDependenciesPromises: Promise<void>[] = []
this.compiler = await compile(content, {
from: this.enableSourceMaps ? this.id : undefined,
base: inputBase,
shouldRewriteUrls: true,
onDependency: (path) => {
@ -328,8 +343,13 @@ class Root {
let code = this.compiler.build([...this.candidates])
DEBUG && I.end('Build CSS')
DEBUG && I.start('Build Source Map')
let map = this.enableSourceMaps ? toSourceMap(this.compiler.buildSourceMap()).raw : undefined
DEBUG && I.end('Build Source Map')
return {
code,
map,
}
}