Skip to content

Commit 5fa1926

Browse files
committed
Add source map support to Vite
1 parent dbd9459 commit 5fa1926

2 files changed

Lines changed: 117 additions & 1 deletion

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { candidate, css, fetchStyles, html, json, retryAssertion, test, ts } from '../utils'
2+
3+
test(
4+
`dev build`,
5+
{
6+
fs: {
7+
'package.json': json`
8+
{
9+
"type": "module",
10+
"dependencies": {
11+
"@tailwindcss/vite": "workspace:^",
12+
"tailwindcss": "workspace:^"
13+
},
14+
"devDependencies": {
15+
"lightningcss": "^1.26.0",
16+
"vite": "^6"
17+
}
18+
}
19+
`,
20+
'vite.config.ts': ts`
21+
import tailwindcss from '@tailwindcss/vite'
22+
import { defineConfig } from 'vite'
23+
24+
export default defineConfig({
25+
plugins: [tailwindcss()],
26+
css: {
27+
devSourcemap: true,
28+
},
29+
build: {
30+
sourcemap: true,
31+
},
32+
})
33+
`,
34+
'index.html': html`
35+
<head>
36+
<link rel="stylesheet" href="./src/index.css" />
37+
</head>
38+
<body>
39+
<div class="flex">Hello, world!</div>
40+
</body>
41+
`,
42+
'src/index.css': css`
43+
@import 'tailwindcss/utilities';
44+
/* */
45+
`,
46+
},
47+
},
48+
async ({ fs, spawn, expect, parseSourceMap }) => {
49+
// Source maps only work in development mode in Vite
50+
let process = await spawn('pnpm vite dev')
51+
await process.onStdout((m) => m.includes('ready in'))
52+
53+
let url = ''
54+
await process.onStdout((m) => {
55+
let match = /Local:\s*(http.*)\//.exec(m)
56+
if (match) url = match[1]
57+
return Boolean(url)
58+
})
59+
60+
let styles = await retryAssertion(async () => {
61+
let styles = await fetchStyles(url, '/index.html')
62+
63+
// Wait until we have the right CSS
64+
expect(styles).toContain(candidate`flex`)
65+
66+
return styles
67+
})
68+
69+
// Make sure we can find a source map
70+
let map = parseSourceMap(styles)
71+
72+
expect(map.at(1, 0)).toMatchObject({
73+
source: null,
74+
original: '(none)',
75+
generated: '/*! tailwi...',
76+
})
77+
78+
expect(map.at(2, 0)).toMatchObject({
79+
source: expect.stringContaining('node_modules/tailwindcss/utilities.css'),
80+
original: '@tailwind...',
81+
generated: '.flex {...',
82+
})
83+
84+
expect(map.at(3, 2)).toMatchObject({
85+
source: expect.stringContaining('node_modules/tailwindcss/utilities.css'),
86+
original: '@tailwind...',
87+
generated: 'display: f...',
88+
})
89+
90+
expect(map.at(4, 0)).toMatchObject({
91+
source: null,
92+
original: '(none)',
93+
generated: '}...',
94+
})
95+
},
96+
)

packages/@tailwindcss-vite/src/index.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { compile, env, Features, Instrumentation, normalizePath, optimize } from '@tailwindcss/node'
1+
import {
2+
compile,
3+
env,
4+
Features,
5+
Instrumentation,
6+
normalizePath,
7+
optimize,
8+
toSourceMap,
9+
} from '@tailwindcss/node'
210
import { clearRequireCache } from '@tailwindcss/node/require-cache'
311
import { Scanner } from '@tailwindcss/oxide'
412
import fs from 'node:fs/promises'
@@ -37,6 +45,9 @@ export default function tailwindcss(): Plugin[] {
3745
return new Root(
3846
id,
3947
config!.root,
48+
// Currently, Vite only supports CSS source maps in development and they
49+
// are off by default. Check to see if we need them or not.
50+
config?.css.devSourcemap ?? false,
4051
customCssResolver,
4152
customJsResolver,
4253
)
@@ -108,6 +119,7 @@ export default function tailwindcss(): Plugin[] {
108119
DEBUG && I.start('[@tailwindcss/vite] Optimize CSS')
109120
result = optimize(result.code, {
110121
minify,
122+
map: result.map,
111123
})
112124
DEBUG && I.end('[@tailwindcss/vite] Optimize CSS')
113125

@@ -180,6 +192,7 @@ class Root {
180192
private id: string,
181193
private base: string,
182194

195+
private enableSourceMaps: boolean,
183196
private customCssResolver: (id: string, base: string) => Promise<string | false | undefined>,
184197
private customJsResolver: (id: string, base: string) => Promise<string | false | undefined>,
185198
) {}
@@ -193,6 +206,7 @@ class Root {
193206
): Promise<
194207
| {
195208
code: string
209+
map: string | undefined
196210
}
197211
| false
198212
> {
@@ -227,6 +241,7 @@ class Root {
227241
DEBUG && I.start('Setup compiler')
228242
let addBuildDependenciesPromises: Promise<void>[] = []
229243
this.compiler = await compile(content, {
244+
from: this.enableSourceMaps ? this.id : undefined,
230245
base: inputBase,
231246
shouldRewriteUrls: true,
232247
onDependency: (path) => {
@@ -328,8 +343,13 @@ class Root {
328343
let code = this.compiler.build([...this.candidates])
329344
DEBUG && I.end('Build CSS')
330345

346+
DEBUG && I.start('Build Source Map')
347+
let map = this.enableSourceMaps ? toSourceMap(this.compiler.buildSourceMap()).raw : undefined
348+
DEBUG && I.end('Build Source Map')
349+
331350
return {
332351
code,
352+
map,
333353
}
334354
}
335355

0 commit comments

Comments
 (0)