Skip to content

Commit 8dbebee

Browse files
qnpShinigami92
andauthored
fix(css): properly pass options to stylus compiler, fix #2587 (#2860)
Co-authored-by: Shinigami <[email protected]>
1 parent 8b02abf commit 8dbebee

File tree

12 files changed

+169
-12
lines changed

12 files changed

+169
-12
lines changed

packages/playground/css/__tests__/css.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,16 @@ test('postcss config', async () => {
5656
test('sass', async () => {
5757
const imported = await page.$('.sass')
5858
const atImport = await page.$('.sass-at-import')
59+
const atImportAlias = await page.$('.sass-at-import-alias')
5960
const partialImport = await page.$('.sass-partial')
6061

6162
expect(await getColor(imported)).toBe('orange')
6263
expect(await getColor(atImport)).toBe('olive')
6364
expect(await getBg(atImport)).toMatch(isBuild ? /base64/ : '/nested/icon.png')
65+
expect(await getColor(atImportAlias)).toBe('olive')
66+
expect(await getBg(atImportAlias)).toMatch(
67+
isBuild ? /base64/ : '/nested/icon.png'
68+
)
6469
expect(await getColor(partialImport)).toBe('orchid')
6570

6671
editFile('sass.scss', (code) =>
@@ -82,10 +87,15 @@ test('sass', async () => {
8287
test('less', async () => {
8388
const imported = await page.$('.less')
8489
const atImport = await page.$('.less-at-import')
90+
const atImportAlias = await page.$('.less-at-import-alias')
8591

8692
expect(await getColor(imported)).toBe('blue')
8793
expect(await getColor(atImport)).toBe('darkslateblue')
8894
expect(await getBg(atImport)).toMatch(isBuild ? /base64/ : '/nested/icon.png')
95+
expect(await getColor(atImportAlias)).toBe('darkslateblue')
96+
expect(await getBg(atImportAlias)).toMatch(
97+
isBuild ? /base64/ : '/nested/icon.png'
98+
)
8999

90100
editFile('less.less', (code) => code.replace('@color: blue', '@color: red'))
91101
await untilUpdated(() => getColor(imported), 'red')
@@ -96,6 +106,35 @@ test('less', async () => {
96106
await untilUpdated(() => getColor(atImport), 'blue')
97107
})
98108

109+
test('stylus', async () => {
110+
const imported = await page.$('.stylus')
111+
const additionalData = await page.$('.stylus-additional-data')
112+
const relativeImport = await page.$('.stylus-import')
113+
const relativeImportAlias = await page.$('.stylus-import-alias')
114+
const optionsRelativeImport = await page.$('.stylus-options-relative-import')
115+
const optionsAbsoluteImport = await page.$('.stylus-options-absolute-import')
116+
117+
expect(await getColor(imported)).toBe('blue')
118+
expect(await getColor(additionalData)).toBe('orange')
119+
expect(await getColor(relativeImport)).toBe('darkslateblue')
120+
expect(await getColor(relativeImportAlias)).toBe('darkslateblue')
121+
expect(await getBg(relativeImportAlias)).toMatch(
122+
isBuild ? /base64/ : '/nested/icon.png'
123+
)
124+
expect(await getColor(optionsRelativeImport)).toBe('green')
125+
expect(await getColor(optionsAbsoluteImport)).toBe('red')
126+
127+
editFile('stylus.styl', (code) =>
128+
code.replace('$color ?= blue', '$color ?= red')
129+
)
130+
await untilUpdated(() => getColor(imported), 'red')
131+
132+
editFile('nested/nested.styl', (code) =>
133+
code.replace('color: darkslateblue', 'color: blue')
134+
)
135+
await untilUpdated(() => getColor(relativeImport), 'blue')
136+
})
137+
99138
test('css modules', async () => {
100139
const imported = await page.$('.modules')
101140
expect(await getColor(imported)).toBe('turquoise')
@@ -133,6 +172,10 @@ test('@import dependency w/ sass entry', async () => {
133172
expect(await getColor('.css-dep-sass')).toBe('orange')
134173
})
135174

175+
test('@import dependency w/ stylus entry', async () => {
176+
expect(await getColor('.css-dep-stylus')).toBe('red')
177+
})
178+
136179
test('async chunk', async () => {
137180
const el = await page.$('.async')
138181
expect(await getColor(el)).toBe('teal')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.css-dep-stylus
2+
color red

packages/playground/css/index.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ <h1>CSS</h1>
4040
<p>Imported Less string:</p>
4141
<pre class="imported-less"></pre>
4242

43+
<p class="stylus">Stylus: This should be blue</p>
44+
<p class="stylus-additional-data">
45+
Stylus additionalData: This should be orange
46+
</p>
47+
<p class="stylus-import">@import from Stylus: This should be darkslateblue</p>
48+
<p class="stylus-import-alias">
49+
@import from Stylus: This should be darkslateblue and have bg image which
50+
url contains alias
51+
</p>
52+
<p class="stylus-options-relative-import">
53+
Stylus import (relative path) via vite config preprocessor options: This
54+
should be green
55+
</p>
56+
<p class="stylus-options-absolute-import">
57+
Stylus import (absolute path) via vite config preprocessor options: This
58+
should be red
59+
</p>
60+
<p>Imported Stylus string:</p>
61+
<pre class="imported-stylus"></pre>
62+
4363
<p class="modules">CSS modules: this should be turquoise</p>
4464
<p>Imported CSS module:</p>
4565
<pre class="modules-code"></pre>
@@ -54,6 +74,9 @@ <h1>CSS</h1>
5474
<p class="css-dep-sass">
5575
@import dependency w/ sass enrtrypoints: this should be orange
5676
</p>
77+
<p class="css-dep-stylus">
78+
@import dependency w/ styl enrtrypoints: this should be red
79+
</p>
5780
</div>
5881

5982
<script type="module" src="./main.js"></script>

packages/playground/css/main.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ text('.imported-sass', sass)
77
import less from './less.less'
88
text('.imported-less', less)
99

10+
import stylus from './stylus.styl'
11+
text('.imported-stylus', stylus)
12+
1013
import mod from './mod.module.css'
1114
document.querySelector('.modules').classList.add(mod['apply-color'])
1215
text('.modules-code', JSON.stringify(mod, null, 2))
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.stylus-import
2+
color darkslateblue
3+
4+
.stylus-import-alias
5+
color darkslateblue
6+
background url('@/nested/icon.png') 10px no-repeat
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.stylus-options-absolute-import
2+
/* imported via vite.config.js */
3+
color red
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.stylus-options-relative-import
2+
/* imported via vite.config.js */
3+
color green

packages/playground/css/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
"serve": "vite preview"
1010
},
1111
"devDependencies": {
12+
"css-dep": "link:./css-dep",
1213
"less": "^4.1.0",
1314
"postcss-nested": "^5.0.3",
1415
"sass": "^1.32.5",
15-
"css-dep": "link:./css-dep"
16+
"stylus": "^0.54.8"
1617
}
1718
}

packages/playground/css/stylus.styl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import './nested/nested'
2+
@import 'css-dep'; // package w/ styl entry points
3+
4+
$color ?= blue
5+
6+
.stylus
7+
color $color
8+
9+
.stylus-additional-data
10+
/* injected via vite.config.js */
11+
color $injectedColor

packages/playground/css/vite.config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const path = require('path')
12
/**
23
* @type {import('vite').UserConfig}
34
*/
@@ -32,6 +33,13 @@ module.exports = {
3233
preprocessorOptions: {
3334
scss: {
3435
additionalData: `$injectedColor: orange;`
36+
},
37+
styl: {
38+
additionalData: `$injectedColor ?= orange`,
39+
imports: [
40+
'./options/relative-import.styl',
41+
path.join(__dirname, 'options/absolute-import.styl')
42+
]
3543
}
3644
}
3745
}

packages/vite/src/node/plugins/css.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ import {
3535
import MagicString from 'magic-string'
3636
import * as Postcss from 'postcss'
3737
import type Sass from 'sass'
38-
import type Stylus from 'stylus'
38+
// We need to disable check of extraneous import which is buggy for stylus,
39+
// and causes the CI tests fail, see: https://github.com/vitejs/vite/pull/2860
40+
import type Stylus from 'stylus' // eslint-disable-line node/no-extraneous-import
3941
import type Less from 'less'
4042
import { Alias } from 'types/alias'
4143

@@ -1104,18 +1106,31 @@ function createViteLessPlugin(
11041106
}
11051107

11061108
// .styl
1107-
const styl: StylePreprocessor = (source, root, options) => {
1109+
const styl: StylePreprocessor = async (source, root, options) => {
11081110
const nodeStylus = loadPreprocessor(PreprocessLang.stylus, root)
1111+
// Get source with preprocessor options.additionalData. Make sure a new line separator
1112+
// is added to avoid any render error, as added stylus content may not have semi-colon separators
1113+
source = await getSource(
1114+
source,
1115+
options.filename,
1116+
options.additionalData,
1117+
'\n'
1118+
)
1119+
// Get preprocessor options.imports dependencies as stylus
1120+
// does not return them with its builtin `.deps()` method
1121+
const importsDeps = (options.imports ?? []).map((dep: string) =>
1122+
path.resolve(dep)
1123+
)
11091124
try {
1110-
const ref = nodeStylus(source)
1125+
const ref = nodeStylus(source, options)
11111126

1112-
Object.keys(options).forEach((key) => ref.set(key, options[key]))
11131127
// if (map) ref.set('sourcemap', { inline: false, comment: false })
11141128

11151129
const result = ref.render()
11161130

11171131
// @ts-expect-error: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/51919
1118-
const deps = ref.deps()
1132+
// Concat imports deps with computed deps
1133+
const deps = [...ref.deps(), ...importsDeps]
11191134

11201135
return { code: result, errors: [], deps }
11211136
} catch (e) {
@@ -1126,13 +1141,14 @@ const styl: StylePreprocessor = (source, root, options) => {
11261141
function getSource(
11271142
source: string,
11281143
filename: string,
1129-
additionalData?: PreprocessorAdditionalData
1144+
additionalData?: PreprocessorAdditionalData,
1145+
sep: string = ''
11301146
): string | Promise<string> {
11311147
if (!additionalData) return source
11321148
if (typeof additionalData === 'function') {
11331149
return additionalData(source, filename)
11341150
}
1135-
return additionalData + source
1151+
return additionalData + sep + source
11361152
}
11371153

11381154
const preProcessors = Object.freeze({

yarn.lock

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,6 +2483,23 @@ css-color-names@^1.0.1:
24832483
version "0.0.0"
24842484
uid ""
24852485

2486+
css-parse@~2.0.0:
2487+
version "2.0.0"
2488+
resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4"
2489+
integrity sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=
2490+
dependencies:
2491+
css "^2.0.0"
2492+
2493+
css@^2.0.0:
2494+
version "2.2.4"
2495+
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
2496+
integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==
2497+
dependencies:
2498+
inherits "^2.0.3"
2499+
source-map "^0.6.1"
2500+
source-map-resolve "^0.5.2"
2501+
urix "^0.1.0"
2502+
24862503
cssesc@^3.0.0:
24872504
version "3.0.0"
24882505
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -2564,6 +2581,13 @@ debug@^3.2.6:
25642581
dependencies:
25652582
ms "^2.1.1"
25662583

2584+
debug@~3.1.0:
2585+
version "3.1.0"
2586+
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
2587+
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
2588+
dependencies:
2589+
ms "2.0.0"
2590+
25672591
decamelize-keys@^1.1.0:
25682592
version "1.1.0"
25692593
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
@@ -5417,7 +5441,7 @@ mixin-deep@^1.2.0:
54175441
for-in "^1.0.2"
54185442
is-extendable "^1.0.1"
54195443

5420-
5444+
54215445
version "1.0.4"
54225446
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
54235447
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@@ -6862,7 +6886,7 @@ safe-regex@^1.1.0:
68626886
dependencies:
68636887
ret "~0.1.10"
68646888

6865-
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
6889+
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@^2.1.2, safer-buffer@~2.1.0:
68666890
version "2.1.2"
68676891
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
68686892
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -6889,7 +6913,7 @@ sass@^1.30.0, sass@^1.32.5:
68896913
dependencies:
68906914
chokidar ">=2.0.0 <4.0.0"
68916915

6892-
sax@^1.2.4:
6916+
sax@^1.2.4, sax@~1.2.4:
68936917
version "1.2.4"
68946918
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
68956919
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -7115,7 +7139,7 @@ snapdragon@^0.8.1:
71157139
source-map-resolve "^0.5.0"
71167140
use "^3.1.0"
71177141

7118-
source-map-resolve@^0.5.0:
7142+
source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
71197143
version "0.5.3"
71207144
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
71217145
integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==
@@ -7426,6 +7450,20 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1
74267450
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
74277451
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
74287452

7453+
stylus@^0.54.8:
7454+
version "0.54.8"
7455+
resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.8.tgz#3da3e65966bc567a7b044bfe0eece653e099d147"
7456+
integrity sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==
7457+
dependencies:
7458+
css-parse "~2.0.0"
7459+
debug "~3.1.0"
7460+
glob "^7.1.6"
7461+
mkdirp "~1.0.4"
7462+
safer-buffer "^2.1.2"
7463+
sax "~1.2.4"
7464+
semver "^6.3.0"
7465+
source-map "^0.7.3"
7466+
74297467
supports-color@^2.0.0:
74307468
version "2.0.0"
74317469
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"

0 commit comments

Comments
 (0)