svelte-windicss-preprocess-exp

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.


Why not use svelte-windicss-preprocess?

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.


Installation

npm install --save-dev svelte-windicss-preprocess-exp

Configuration

// 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

Typescript

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(),
  ]),
};

Base styles

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>

Compatibilities

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.

Class attribute

<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>

Class directive

<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>

@apply directive

<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>

@screen directive

<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>

@variants directive

<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>

Top categories

svelte logo

Need a Svelte website built?

Hire a professional Svelte developer today.
Loading Svelte Themes