Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(css): add preprocessor option to define stylus vars & funcs #7227

Merged
merged 7 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 15 additions & 2 deletions docs/config/shared-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,15 @@ Note if an inline config is provided, Vite will not search for other PostCSS con

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

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({
Expand All @@ -235,8 +243,13 @@ export default defineConfig({
scss: {
additionalData: `$injectedColor: orange;`,
},
less: {
math: 'parens-division',
},
styl: {
additionalData: `$injectedColor ?= orange`,
define: {
$specialColor: new stylus.Parser('#33C5FF').peek().val,
},
},
},
},
Expand Down
18 changes: 17 additions & 1 deletion packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,10 @@ type StylePreprocessorOptions = {

type SassStylePreprocessorOptions = StylePreprocessorOptions & Sass.Options

type StylusStylePreprocessorOptions = StylePreprocessorOptions & {
define?: Record<string, any>
}

type StylePreprocessor = (
source: string,
root: string,
Expand All @@ -1467,6 +1471,13 @@ type SassStylePreprocessor = (
resolvers: CSSAtImportResolvers,
) => StylePreprocessorResults | Promise<StylePreprocessorResults>

type StylusStylePreprocessor = (
source: string,
root: string,
options: StylusStylePreprocessorOptions,
resolvers: CSSAtImportResolvers,
) => StylePreprocessorResults | Promise<StylePreprocessorResults>

export interface StylePreprocessorResults {
code: string
map?: ExistingRawSourceMap | undefined
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions playground/css/__tests__/css.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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'),
Expand Down
8 changes: 8 additions & 0 deletions playground/css/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ <h1>CSS</h1>
Stylus import (absolute path) via vite config preprocessor options: This
should be red
</p>
<p class="stylus-options-define-var">
Stylus define variable via vite config preprocessor options: This should be
rgb(51, 197, 255)
</p>
<p class="stylus-options-define-func">
Stylus define function via vite config preprocessor options: This should be
rgb(255, 0, 98)
</p>
<p>Imported Stylus string:</p>
<pre class="imported-stylus"></pre>

Expand Down
8 changes: 8 additions & 0 deletions playground/css/stylus.styl
Original file line number Diff line number Diff line change
Expand Up @@ -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()
5 changes: 5 additions & 0 deletions playground/css/vite.config.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -68,6 +69,10 @@ export default defineConfig({
'./options/relative-import.styl',
path.join(__dirname, 'options/absolute-import.styl'),
],
define: {
$definedColor: new stylus.Parser('#33C5FF').peek().val,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got a type error here after merging but seems it should be an issue with my editor. cc @bluwy just in case

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm... it is a real issue 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like Parser is an internal class we shouldn't be using

    //#region Internal Classes

    export class Visitor {
    }

    export class Parser {
    }

    export class Evaluator {
    }

    export class Compiler {
    }

    //#endregion

Ignoring the error in the test to make this one pass for now: 556de6e (#7227)

definedFunction: () => new stylus.nodes.RGBA(255, 0, 98, 1),
},
},
},
},
Expand Down