Skip to content

Commit 38a655f

Browse files
authored
feat: css sourcemap support during dev (#7173)
1 parent 68d76c9 commit 38a655f

40 files changed

+1210
-70
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { isBuild } from 'testUtils'
2+
3+
if (isBuild) {
4+
test('should not output sourcemap warning (#4939)', () => {
5+
serverLogs.forEach((log) => {
6+
expect(log).not.toMatch('Sourcemap is likely to be incorrect')
7+
})
8+
})
9+
} else {
10+
test('this file only includes test for build', () => {
11+
expect(true).toBe(true)
12+
})
13+
}
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import { fromComment } from 'convert-source-map'
2+
import { URL } from 'url'
3+
import { normalizePath } from 'vite'
4+
import { isBuild, testDir } from 'testUtils'
5+
6+
if (!isBuild) {
7+
const root = normalizePath(testDir)
8+
9+
const getStyleTagContentIncluding = async (content: string) => {
10+
const styles = await page.$$('style')
11+
for (const style of styles) {
12+
const text = await style.textContent()
13+
if (text.includes(content)) {
14+
return text
15+
}
16+
}
17+
throw new Error('Not found')
18+
}
19+
20+
const extractSourcemap = (content: string) => {
21+
const lines = content.trim().split('\n')
22+
return fromComment(lines[lines.length - 1]).toObject()
23+
}
24+
25+
const formatSourcemapForSnapshot = (map: any) => {
26+
const m = { ...map }
27+
delete m.file
28+
delete m.names
29+
m.sources = m.sources.map((source) => source.replace(root, '/root'))
30+
return m
31+
}
32+
33+
test('linked css', async () => {
34+
const res = await page.request.get(
35+
new URL('./linked.css', page.url()).href,
36+
{
37+
headers: {
38+
accept: 'text/css'
39+
}
40+
}
41+
)
42+
const css = await res.text()
43+
const lines = css.split('\n')
44+
expect(lines[lines.length - 1].includes('/*')).toBe(false) // expect no sourcemap
45+
})
46+
47+
test('linked css with import', async () => {
48+
const res = await page.request.get(
49+
new URL('./linked-with-import.css', page.url()).href,
50+
{
51+
headers: {
52+
accept: 'text/css'
53+
}
54+
}
55+
)
56+
const css = await res.text()
57+
const map = extractSourcemap(css)
58+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
59+
Object {
60+
"mappings": "AAAA;EACE,UAAU;AACZ;;ACAA;EACE,UAAU;AACZ",
61+
"sources": Array [
62+
"/root/be-imported.css",
63+
"/root/linked-with-import.css",
64+
],
65+
"sourcesContent": Array [
66+
".be-imported {
67+
color: red;
68+
}
69+
",
70+
"@import '@/be-imported.css';
71+
72+
.linked-with-import {
73+
color: red;
74+
}
75+
",
76+
],
77+
"version": 3,
78+
}
79+
`)
80+
})
81+
82+
test('imported css', async () => {
83+
const css = await getStyleTagContentIncluding('.imported ')
84+
const map = extractSourcemap(css)
85+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
86+
Object {
87+
"mappings": "AAAA,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACX,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACb,CAAC;",
88+
"sources": Array [
89+
"/root/imported.css",
90+
],
91+
"sourcesContent": Array [
92+
".imported {
93+
color: red;
94+
}
95+
",
96+
],
97+
"version": 3,
98+
}
99+
`)
100+
})
101+
102+
test('imported css with import', async () => {
103+
const css = await getStyleTagContentIncluding('.imported-with-import ')
104+
const map = extractSourcemap(css)
105+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
106+
Object {
107+
"mappings": "AAAA;EACE,UAAU;AACZ;;ACAA;EACE,UAAU;AACZ",
108+
"sources": Array [
109+
"/root/be-imported.css",
110+
"/root/imported-with-import.css",
111+
],
112+
"sourcesContent": Array [
113+
".be-imported {
114+
color: red;
115+
}
116+
",
117+
"@import '@/be-imported.css';
118+
119+
.imported-with-import {
120+
color: red;
121+
}
122+
",
123+
],
124+
"version": 3,
125+
}
126+
`)
127+
})
128+
129+
test('imported sass', async () => {
130+
const css = await getStyleTagContentIncluding('.imported-sass ')
131+
const map = extractSourcemap(css)
132+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
133+
Object {
134+
"mappings": "AACE;EACE",
135+
"sources": Array [
136+
"/root/imported.sass",
137+
],
138+
"sourcesContent": Array [
139+
".imported
140+
&-sass
141+
color: red
142+
",
143+
],
144+
"version": 3,
145+
}
146+
`)
147+
})
148+
149+
test('imported sass module', async () => {
150+
const css = await getStyleTagContentIncluding('._imported-sass-module_')
151+
const map = extractSourcemap(css)
152+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
153+
Object {
154+
"mappings": "AACE;EACE",
155+
"sources": Array [
156+
"/root/imported.module.sass",
157+
],
158+
"sourcesContent": Array [
159+
".imported
160+
&-sass-module
161+
color: red
162+
",
163+
],
164+
"version": 3,
165+
}
166+
`)
167+
})
168+
169+
test('imported less', async () => {
170+
const css = await getStyleTagContentIncluding('.imported-less ')
171+
const map = extractSourcemap(css)
172+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
173+
Object {
174+
"mappings": "AACE;EACE",
175+
"sources": Array [
176+
"/root/imported.less",
177+
],
178+
"sourcesContent": Array [
179+
".imported {
180+
&-less {
181+
color: @color;
182+
}
183+
}
184+
",
185+
],
186+
"version": 3,
187+
}
188+
`)
189+
})
190+
191+
test('imported stylus', async () => {
192+
const css = await getStyleTagContentIncluding('.imported-stylus ')
193+
const map = extractSourcemap(css)
194+
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
195+
Object {
196+
"mappings": "AACE;EACE,cAAM",
197+
"sources": Array [
198+
"/root/imported.styl",
199+
],
200+
"sourcesContent": Array [
201+
".imported
202+
&-stylus
203+
color blue-red-mixed
204+
",
205+
],
206+
"version": 3,
207+
}
208+
`)
209+
})
210+
} else {
211+
test('this file only includes test for serve', () => {
212+
expect(true).toBe(true)
213+
})
214+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.be-imported {
2+
color: red;
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import '@/be-imported.css';
2+
3+
.imported-with-import {
4+
color: red;
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.imported {
2+
color: red;
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.imported {
2+
&-less {
3+
color: @color;
4+
}
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.imported
2+
&-sass-module
3+
color: red
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.imported
2+
&-sass
3+
color: red
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.imported
2+
&-stylus
3+
color blue-red-mixed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<link rel="stylesheet" href="./linked.css" />
2+
<link rel="stylesheet" href="./linked-with-import.css" />
3+
4+
<div class="wrapper">
5+
<h1>CSS Sourcemap</h1>
6+
7+
<p class="linked">&lt;linked&gt;: no import</p>
8+
<p class="linked-with-import">&lt;linked&gt;: with import</p>
9+
10+
<p class="imported">&lt;imported&gt;: no import</p>
11+
<p class="imported-with-import">&lt;imported&gt;: with import</p>
12+
13+
<p class="imported-sass">&lt;imported sass&gt;</p>
14+
<p class="imported-sass-module">&lt;imported sass&gt; with module</p>
15+
16+
<p class="imported-less">&lt;imported less&gt; with string additionalData</p>
17+
18+
<p class="imported-stylus">&lt;imported stylus&gt;</p>
19+
</div>
20+
21+
<script type="module">
22+
import './imported.css'
23+
import './imported-with-import.css'
24+
25+
import './imported.sass'
26+
import sassModule from './imported.module.sass'
27+
28+
document
29+
.querySelector('.imported-sass-module')
30+
.classList.add(sassModule['imported-sass-module'])
31+
32+
import './imported.less'
33+
34+
import './imported.styl'
35+
</script>

0 commit comments

Comments
 (0)