A svelte preprocessor to compile TailwindCSS at build time based on WindiCSS compiler.
This package uses Svelte's and WindiCSS's own parser to carefully target only class attribute, class directives, @apply
directives, @variants
directives and @screen
directives.
The package svelte-windicss-preprocess
as of v3 still uses a custom parser built with regular expressions. Regular expressions are not the right tool to parse and preprocess a complex markup like Svelte. As a result, it preprocesses statements in the wrong places (see issue #43, #44 and #46). It was decided by the contributors to forego the use of Svelte parser and continue with regular expressions.
Until the svelte-windicss-preprocess
stabilize their regular expressions, I'll maintain this package as an alternate solution that is, for now, more robust and reliable.
npm install --save-dev svelte-windicss-preprocess-exp
// svelte.config.js
module.exports = {
preprocess: require("svelte-windicss-preprocess-exp").preprocess({
// … see config below
}),
};
Configuration | Description |
---|---|
config |
Either a string that represent the location of tailwind.config.js or the WindiCSS configuration's object .Defaults to undefined .
|
mode |
When set to attribute-only , it only processes class attribute, class directive and variants attribute. When set to directive-only , only @apply , @screen and @variants directive are processed. When not set or undefined , everything is processed.Defaults to undefined
|
includeBaseStyles |
Include TailwindCSS's base style. Defaults to false
|
includeGlobalStyles |
Include global styles. Defaults to true
|
includePluginStyles |
Include plugin styles. Defaults to true
|
ignoreDynamicClassesWarning |
Do not emit warning when using dynamic classes on TailwindCSS's utility classes Defaults to false
|
If you are using Typescript or any other preprocessor, you will need to wrap your preprocessors inside svelte-sequential-preprocessor
. Svelte praser will only understand Javascript, HTML, CSS code.
// svelte.config.js
module.exports = {
preprocess: require("svelte-sequential-preprocessor")([
require("svelte-preprocess").typescript(),
require("svelte-windicss-preprocess-exp").preprocess(),
]),
};
The preprocessor will only compile WindiCSS's style within your component. You are left with the responsibility to include the WindiCSS's base styles with @windicss base;
somewhere in a top-level component's style. The generated base styles will be properly wrapped in :global(…)
.
<div>…</div>
<style>
/* Add this to include WindiCSS's base styles in your component */
@windicss base;
</style>
Attribute's value syntaxe supported : vanilla <div class="foo">…</div>
, mustache tag <div class="font-bold {foo} {bar}">…</div>
and template literal <div class={`font-bold ${template} ${literals}`}>…</div>
. They all get squashed and normalized into a single class attribute with template literal by this preprocessor.
Dynamic classes are only handled in class directives. They are left untouched by the preprocessor. If you requires to process dynamic classes within mustache tag or template literal, you can call WindiCSS's processor at runtime to generate appropriated styles.
<h1 class="text-4xl font-extrabold">Hello World</h1>
↓↓↓
<h1 class={`windi-mqgc06`}>Hello World</h1>
<style>
.windi-mqgc06 {
font-size: 2.25rem;
line-height: 2.5rem;
font-weight: 800;
}
</style>
<h1 class:text-4xl={large} class:font-extra-bold={bold} class:foo class="text-indigo-600">
Hello World
</h1>
↓↓↓
<h1 class={`windi-u7qal3 ${large ? 'text-4xl' : ''} ${bold ? 'font-extra-bold' : ''} ${foo ? 'foo' : ''}`}>
Hello World
</h1>
<style>
.font-extra-bold {
font-weight: 700;
}
.text-4xl {
font-size: 2.25rem;
line-height: 2.5rem;
}
.windi-u7qal3 {
--tw-text-opacity: 1;
color: rgba(79, 70, 229, var(--tw-text-opacity));
}
</style>
<h1 class="foo">Hello World</h1>
<style>
.foo {
@apply text-4xl;
}
</style>
↓↓↓
<h1 class={`foo`}>Hello World</h1>
<style>
.foo {
font-size: 2.25rem;
line-height: 2.5rem;
}
</style>
<h1 class="foo">Hello World</h1>
<style>
@screen sm {
.foo {
font-weight: bold;
}
}
</style>
↓↓↓
<h1 class={`foo`}>Hello World</h1>
<style>
@media (min-width: 640px) {
.foo {
font-weight: bold;
}
}
</style>
<h1 class="foo">Hello World</h1>
<style>
@variants active, hover {
.foo {
font-weight: bold;
}
}
</style>
↓↓↓
<h1 class={`foo`}>Hello World</h1>
<style>
.foo:active {
font-weight: bold;
}
.foo:hover {
font-weight: bold;
}
</style>