From 5968becf5970125b90b503a53208e2dff29b02bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Risoud?=
Date: Mon, 6 Mar 2023 18:58:14 +0100
Subject: [PATCH] feat(css): add preprocessor option to define stylus vars &
funcs (#7227)
Co-authored-by: bluwy
---
docs/config/shared-options.md | 17 +++++++++++++++--
packages/vite/src/node/plugins/css.ts | 18 +++++++++++++++++-
playground/css/__tests__/css.spec.ts | 4 ++++
playground/css/index.html | 8 ++++++++
playground/css/stylus.styl | 8 ++++++++
playground/css/vite.config.js | 5 +++++
6 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/docs/config/shared-options.md b/docs/config/shared-options.md
index 3fb77ec43..7dacf0e82 100644
--- a/docs/config/shared-options.md
+++ b/docs/config/shared-options.md
@@ -226,7 +226,15 @@ Note if an inline config is provided, Vite will not search for other PostCSS con
- **Type:** `Record`
-Specify options to pass to CSS pre-processors. The file extensions are used as keys for the options. Example:
+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:
+
+- `sass`/`scss` - [Options](https://sass-lang.com/documentation/js-api/interfaces/LegacyStringOptions).
+- `less` - [Options](https://lesscss.org/usage/#less-options).
+- `styl`/`stylus` - Only [`define`](https://stylus-lang.com/docs/js.html#define-name-node) is supported, which can be passed as an object.
+
+All preprocessor options also support the `additionalData` option, which can be used to inject extra code for each style content.
+
+Example:
```js
export default defineConfig({
@@ -235,8 +243,13 @@ export default defineConfig({
scss: {
additionalData: `$injectedColor: orange;`,
},
+ less: {
+ math: 'parens-division',
+ },
styl: {
- additionalData: `$injectedColor ?= orange`,
+ define: {
+ $specialColor: new stylus.nodes.RGBA(51, 197, 255, 1),
+ },
},
},
},
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 38ca4cac2..810498df1 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -1453,6 +1453,10 @@ type StylePreprocessorOptions = {
type SassStylePreprocessorOptions = StylePreprocessorOptions & Sass.Options
+type StylusStylePreprocessorOptions = StylePreprocessorOptions & {
+ define?: Record
+}
+
type StylePreprocessor = (
source: string,
root: string,
@@ -1467,6 +1471,13 @@ type SassStylePreprocessor = (
resolvers: CSSAtImportResolvers,
) => StylePreprocessorResults | Promise
+type StylusStylePreprocessor = (
+ source: string,
+ root: string,
+ options: StylusStylePreprocessorOptions,
+ resolvers: CSSAtImportResolvers,
+) => StylePreprocessorResults | Promise
+
export interface StylePreprocessorResults {
code: string
map?: ExistingRawSourceMap | undefined
@@ -1847,7 +1858,7 @@ function createViteLessPlugin(
}
// .styl
-const styl: StylePreprocessor = async (source, root, options) => {
+const styl: StylusStylePreprocessor = async (source, root, options) => {
const nodeStylus = loadPreprocessor(PreprocessLang.stylus, root)
// Get source with preprocessor options.additionalData. Make sure a new line separator
// 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) => {
)
try {
const ref = nodeStylus(content, options)
+ if (options.define) {
+ for (const key in options.define) {
+ ref.define(key, options.define[key])
+ }
+ }
if (options.enableSourcemap) {
ref.set('sourcemap', {
comment: false,
diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts
index c3ae17f0e..9951558fa 100644
--- a/playground/css/__tests__/css.spec.ts
+++ b/playground/css/__tests__/css.spec.ts
@@ -146,6 +146,8 @@ test('stylus', async () => {
const relativeImportAlias = await page.$('.stylus-import-alias')
const optionsRelativeImport = await page.$('.stylus-options-relative-import')
const optionsAbsoluteImport = await page.$('.stylus-options-absolute-import')
+ const optionsDefineVar = await page.$('.stylus-options-define-var')
+ const optionsDefineFunc = await page.$('.stylus-options-define-func')
expect(await getColor(imported)).toBe('blue')
expect(await getColor(additionalData)).toBe('orange')
@@ -156,6 +158,8 @@ test('stylus', async () => {
)
expect(await getColor(optionsRelativeImport)).toBe('green')
expect(await getColor(optionsAbsoluteImport)).toBe('red')
+ expect(await getColor(optionsDefineVar)).toBe('rgb(51, 197, 255)')
+ expect(await getColor(optionsDefineFunc)).toBe('rgb(255, 0, 98)')
editFile('stylus.styl', (code) =>
code.replace('$color ?= blue', '$color ?= red'),
diff --git a/playground/css/index.html b/playground/css/index.html
index f520d6514..a90c5dd7e 100644
--- a/playground/css/index.html
+++ b/playground/css/index.html
@@ -72,6 +72,14 @@
Stylus import (absolute path) via vite config preprocessor options: This
should be red
+
+ Stylus define variable via vite config preprocessor options: This should be
+ rgb(51, 197, 255)
+
+
+ Stylus define function via vite config preprocessor options: This should be
+ rgb(255, 0, 98)
+
Imported Stylus string:
diff --git a/playground/css/stylus.styl b/playground/css/stylus.styl
index d43ba92d7..a4e61e6c0 100644
--- a/playground/css/stylus.styl
+++ b/playground/css/stylus.styl
@@ -8,3 +8,11 @@ $color ?= blue
.stylus-additional-data
/* injected via vite.config.js */
color $injectedColor
+
+.stylus-options-define-var
+ /* defined in vite.config.js */
+ color $definedColor
+
+.stylus-options-define-func
+ /* defined in vite.config.js */
+ color definedFunction()
diff --git a/playground/css/vite.config.js b/playground/css/vite.config.js
index 33a99cf50..aa905db51 100644
--- a/playground/css/vite.config.js
+++ b/playground/css/vite.config.js
@@ -1,4 +1,5 @@
import path from 'node:path'
+import stylus from 'stylus'
import { defineConfig } from 'vite'
// trigger scss bug: https://github.com/sass/dart-sass/issues/710
@@ -68,6 +69,10 @@ export default defineConfig({
'./options/relative-import.styl',
path.join(__dirname, 'options/absolute-import.styl'),
],
+ define: {
+ $definedColor: new stylus.nodes.RGBA(51, 197, 255, 1),
+ definedFunction: () => new stylus.nodes.RGBA(255, 0, 98, 1),
+ },
},
},
},