A Svelte preprocessor wrapper with baked-in support for commonly used preprocessors
—
Pug template engine integration for markup preprocessing and global style handling for CSS scope management.
Pug template engine integration for preprocessing markup blocks with full Pug language support.
/**
* Creates Pug preprocessor for markup blocks
* @param options - Pug configuration options
* @returns PreprocessorGroup with markup preprocessing
*/
function pug(options?: Options.Pug): PreprocessorGroup;
namespace Options {
interface Pug {
/** Tag name for markup sections */
markupTagName?: string;
/** Content to prepend to every file */
prependData?: string;
/** Remove common leading whitespace (automatically enabled) */
stripIndent?: boolean;
// Additional Pug options (subset of pug.Options)
// Excludes: 'filename', 'doctype', 'compileDebug' (handled internally)
}
}Usage Examples:
import { pug } from "svelte-preprocess";
// Basic Pug support
const preprocess = {
markup: pug()
};
// Pug with custom configuration
const preprocess = {
markup: pug({
markupTagName: 'template',
// Pug-specific options
pretty: process.env.NODE_ENV === 'development',
filters: {
'markdown': require('marked')
}
})
};
// Pug with global mixins
const preprocess = {
markup: pug({
prependData: `
mixin button(text, type='button')
button(type=type)= text
mixin icon(name)
svg.icon(class=\`icon-\${name}\`)
use(href=\`#icon-\${name}\`)
`
})
};Handles CSS with global attributes, transforming selectors to global scope.
/**
* Creates global style preprocessor for handling global CSS
* @returns PreprocessorGroup with style preprocessing for global styles
*/
function globalStyle(): PreprocessorGroup;
namespace Options {
interface GlobalStyle {
/** Enable source map generation */
sourceMap: boolean;
}
}Usage Examples:
import { globalStyle } from "svelte-preprocess";
// Basic global style support
const preprocess = {
style: globalStyle()
};The global style processor is typically used automatically within the auto preprocessor when PostCSS is available:
<!-- Global styles are automatically processed -->
<style global>
body {
margin: 0;
font-family: system-ui;
}
.global-utility {
display: flex;
align-items: center;
}
</style>
<!-- Scoped styles (normal Svelte behavior) -->
<style>
.component-style {
color: blue;
}
</style>Template processors integrate seamlessly with the auto preprocessor:
import { sveltePreprocess } from "svelte-preprocess";
const preprocess = sveltePreprocess({
// Pug markup processing
pug: {
markupTagName: 'template',
prependData: `
mixin component-wrapper(class='')
div.component(class=class)
block
`
},
// Global style processing (automatic when PostCSS available)
globalStyle: true,
// Works with other preprocessors
scss: true,
postcss: {
plugins: [require('autoprefixer')]
}
});The auto preprocessor detects template languages based on:
<template lang="pug"> or custom markupTagName<style global><!-- Input Pug -->
div.container
h1.title Welcome to Svelte
p.description
| This is a Pug template with
strong dynamic content
| .
ul.list
each item in items
li.item= item.name
<!-- Compiles to HTML -->
<div class="container">
<h1 class="title">Welcome to Svelte</h1>
<p class="description">
This is a Pug template with
<strong>dynamic content</strong>.
</p>
<ul class="list">
{#each items as item}
<li class="item">{item.name}</li>
{/each}
</ul>
</div>Pug templates maintain full Svelte functionality:
<!-- Svelte directives work in Pug -->
script.
export let count = 0;
function increment() {
count += 1;
}
div.counter
h2 Count: #{count}
button(on:click="{increment}") Increment
// Conditional rendering
if count > 5
p.warning High count detected!
// Each blocks
ul
each item, i in items
li(class:active="{i === activeIndex}")= item
style(lang="scss").
.counter {
padding: 1rem;
border: 1px solid #ccc;
.warning {
color: red;
font-weight: bold;
}
}const preprocess = {
markup: pug({
// Custom filters
filters: {
'markdown': (text) => require('marked')(text),
'highlight': (text, options) => require('highlight.js').highlight(text, options).value
},
// Global variables
globals: ['_', 'moment'],
// Custom functions
prependData: `
//- Utility mixins
mixin responsive-image(src, alt)
picture
source(media="(max-width: 768px)" srcset=\`\${src}-mobile.jpg\`)
img(src=src alt=alt loading="lazy")
//- SVG icon helper
mixin icon(name, size='24')
svg(width=size height=size)
use(href=\`#icon-\${name}\`)
`
})
};Global styles are automatically processed when using the auto preprocessor:
const preprocess = sveltePreprocess({
// Global styles processed automatically if PostCSS available
postcss: true, // Enables global style processing
scss: true // Global SCSS styles also supported
});// Explicit global style configuration
const preprocess = sveltePreprocess({
globalStyle: {
sourceMap: true
},
postcss: {
plugins: [require('autoprefixer')]
}
});The global style processor transforms CSS selectors:
/* Input: style with global attribute */
<style global lang="scss">
.button {
padding: 0.5rem 1rem;
&:hover {
background: #f0f0f0;
}
.icon {
margin-right: 0.5rem;
}
}
</style>
/* Output: Transformed to global selectors */
:global(.button) {
padding: 0.5rem 1rem;
}
:global(.button:hover) {
background: #f0f0f0;
}
:global(.button .icon) {
margin-right: 0.5rem;
}<!-- Component template with Pug -->
mixin card(title, variant='default')
article.card(class=`card--${variant}`)
header.card__header
h3.card__title= title
if block('actions')
.card__actions
block actions
.card__content
block content
<!-- Usage -->
+card('My Card', 'primary')
block content
p This is the card content
block actions
button.btn Edit
button.btn Delete/* Global utility styles */
<style global lang="scss">
// Layout utilities
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
// Spacing utilities
@for $i from 1 through 12 {
.p-#{$i} { padding: #{$i * 0.25}rem; }
.m-#{$i} { margin: #{$i * 0.25}rem; }
}
// Responsive utilities
@media (max-width: 768px) {
.hidden-mobile { display: none; }
}
</style><!-- Template with theme classes -->
div.app(class="{theme}")
header.header
h1.title= title
main.content
block content
style(global lang="scss").
.app {
--primary: #007acc;
--background: #ffffff;
--text: #333333;
&.dark {
--primary: #66b3ff;
--background: #1a1a1a;
--text: #ffffff;
}
}
.header {
background: var(--background);
color: var(--text);
}const preprocess = {
markup: pug({
// Enhanced error reporting
compileDebug: process.env.NODE_ENV === 'development',
// Pretty error output
pretty: process.env.NODE_ENV === 'development'
})
};The global style processor will warn when PostCSS is not available:
// This will show a warning if PostCSS is not installed
const preprocess = sveltePreprocess({
globalStyle: true // Requires PostCSS for proper functioning
});interface PugOptions {
/** Tag name for markup sections */
markupTagName?: string;
/** Content to prepend to source */
prependData?: string;
/** Remove leading whitespace (automatically enabled) */
stripIndent?: boolean;
// Additional Pug compiler options (subset of pug.Options)
/** Pretty-print output */
pretty?: boolean;
/** Custom filters */
filters?: Record<string, Function>;
/** Global variables */
globals?: string[];
/** Additional Pug options (excluding filename, doctype, compileDebug) */
[key: string]: any;
}
interface GlobalStyleOptions {
/** Enable source map generation */
sourceMap: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-svelte-preprocess