Skip to content

Commit 5968bec

Browse files
qnpbluwy
andauthored
feat(css): add preprocessor option to define stylus vars & funcs (#7227)
Co-authored-by: bluwy <[email protected]>
1 parent cc92da9 commit 5968bec

File tree

6 files changed

+57
-3
lines changed

6 files changed

+57
-3
lines changed

docs/config/shared-options.md

+15-2
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,15 @@ Note if an inline config is provided, Vite will not search for other PostCSS con
226226

227227
- **Type:** `Record<string, object>`
228228

229-
Specify options to pass to CSS pre-processors. The file extensions are used as keys for the options. Example:
229+
Specify options to pass to CSS pre-processors. The file extensions are used as keys for the options. The supported options for each preprocessors can be found in their respective documentation:
230+
231+
- `sass`/`scss` - [Options](https://sass-lang.com/documentation/js-api/interfaces/LegacyStringOptions).
232+
- `less` - [Options](https://lesscss.org/usage/#less-options).
233+
- `styl`/`stylus` - Only [`define`](https://stylus-lang.com/docs/js.html#define-name-node) is supported, which can be passed as an object.
234+
235+
All preprocessor options also support the `additionalData` option, which can be used to inject extra code for each style content.
236+
237+
Example:
230238

231239
```js
232240
export default defineConfig({
@@ -235,8 +243,13 @@ export default defineConfig({
235243
scss: {
236244
additionalData: `$injectedColor: orange;`,
237245
},
246+
less: {
247+
math: 'parens-division',
248+
},
238249
styl: {
239-
additionalData: `$injectedColor ?= orange`,
250+
define: {
251+
$specialColor: new stylus.nodes.RGBA(51, 197, 255, 1),
252+
},
240253
},
241254
},
242255
},

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,10 @@ type StylePreprocessorOptions = {
14531453

14541454
type SassStylePreprocessorOptions = StylePreprocessorOptions & Sass.Options
14551455

1456+
type StylusStylePreprocessorOptions = StylePreprocessorOptions & {
1457+
define?: Record<string, any>
1458+
}
1459+
14561460
type StylePreprocessor = (
14571461
source: string,
14581462
root: string,
@@ -1467,6 +1471,13 @@ type SassStylePreprocessor = (
14671471
resolvers: CSSAtImportResolvers,
14681472
) => StylePreprocessorResults | Promise<StylePreprocessorResults>
14691473

1474+
type StylusStylePreprocessor = (
1475+
source: string,
1476+
root: string,
1477+
options: StylusStylePreprocessorOptions,
1478+
resolvers: CSSAtImportResolvers,
1479+
) => StylePreprocessorResults | Promise<StylePreprocessorResults>
1480+
14701481
export interface StylePreprocessorResults {
14711482
code: string
14721483
map?: ExistingRawSourceMap | undefined
@@ -1847,7 +1858,7 @@ function createViteLessPlugin(
18471858
}
18481859

18491860
// .styl
1850-
const styl: StylePreprocessor = async (source, root, options) => {
1861+
const styl: StylusStylePreprocessor = async (source, root, options) => {
18511862
const nodeStylus = loadPreprocessor(PreprocessLang.stylus, root)
18521863
// Get source with preprocessor options.additionalData. Make sure a new line separator
18531864
// is added to avoid any render error, as added stylus content may not have semi-colon separators
@@ -1865,6 +1876,11 @@ const styl: StylePreprocessor = async (source, root, options) => {
18651876
)
18661877
try {
18671878
const ref = nodeStylus(content, options)
1879+
if (options.define) {
1880+
for (const key in options.define) {
1881+
ref.define(key, options.define[key])
1882+
}
1883+
}
18681884
if (options.enableSourcemap) {
18691885
ref.set('sourcemap', {
18701886
comment: false,

playground/css/__tests__/css.spec.ts

+4
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ test('stylus', async () => {
146146
const relativeImportAlias = await page.$('.stylus-import-alias')
147147
const optionsRelativeImport = await page.$('.stylus-options-relative-import')
148148
const optionsAbsoluteImport = await page.$('.stylus-options-absolute-import')
149+
const optionsDefineVar = await page.$('.stylus-options-define-var')
150+
const optionsDefineFunc = await page.$('.stylus-options-define-func')
149151

150152
expect(await getColor(imported)).toBe('blue')
151153
expect(await getColor(additionalData)).toBe('orange')
@@ -156,6 +158,8 @@ test('stylus', async () => {
156158
)
157159
expect(await getColor(optionsRelativeImport)).toBe('green')
158160
expect(await getColor(optionsAbsoluteImport)).toBe('red')
161+
expect(await getColor(optionsDefineVar)).toBe('rgb(51, 197, 255)')
162+
expect(await getColor(optionsDefineFunc)).toBe('rgb(255, 0, 98)')
159163

160164
editFile('stylus.styl', (code) =>
161165
code.replace('$color ?= blue', '$color ?= red'),

playground/css/index.html

+8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ <h1>CSS</h1>
7272
Stylus import (absolute path) via vite config preprocessor options: This
7373
should be red
7474
</p>
75+
<p class="stylus-options-define-var">
76+
Stylus define variable via vite config preprocessor options: This should be
77+
rgb(51, 197, 255)
78+
</p>
79+
<p class="stylus-options-define-func">
80+
Stylus define function via vite config preprocessor options: This should be
81+
rgb(255, 0, 98)
82+
</p>
7583
<p>Imported Stylus string:</p>
7684
<pre class="imported-stylus"></pre>
7785

playground/css/stylus.styl

+8
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,11 @@ $color ?= blue
88
.stylus-additional-data
99
/* injected via vite.config.js */
1010
color $injectedColor
11+
12+
.stylus-options-define-var
13+
/* defined in vite.config.js */
14+
color $definedColor
15+
16+
.stylus-options-define-func
17+
/* defined in vite.config.js */
18+
color definedFunction()

playground/css/vite.config.js

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'node:path'
2+
import stylus from 'stylus'
23
import { defineConfig } from 'vite'
34

45
// trigger scss bug: https://github.com/sass/dart-sass/issues/710
@@ -68,6 +69,10 @@ export default defineConfig({
6869
'./options/relative-import.styl',
6970
path.join(__dirname, 'options/absolute-import.styl'),
7071
],
72+
define: {
73+
$definedColor: new stylus.nodes.RGBA(51, 197, 255, 1),
74+
definedFunction: () => new stylus.nodes.RGBA(255, 0, 98, 1),
75+
},
7176
},
7277
},
7378
},

0 commit comments

Comments
 (0)