A Stencil plugin that enables seamless Sass/SCSS preprocessing for Stencil components
npx @tessl/cli install tessl/npm-stencil--sass@3.2.0The @stencil/sass plugin enables seamless Sass/SCSS preprocessing for Stencil components. It provides a pure JavaScript implementation using sass-embedded for compiling Sass files within Stencil projects, offering features like automatic component directory inclusion in import paths, global Sass injection capabilities for variables and mixins, comprehensive warning controls, and full integration with Stencil's plugin architecture.
npm install @stencil/sass --save-dev@stencil/core (>=2.0.0 || >=3.0.0-beta.0 || >= 4.0.0-beta.0 || >= 4.0.0) - Required for plugin integrationimport { sass } from "@stencil/sass";For CommonJS:
const { sass } = require("@stencil/sass");import { Config } from "@stencil/core";
import { sass } from "@stencil/sass";
export const config: Config = {
plugins: [
sass({
// Basic configuration
outputStyle: 'compressed',
sourceMap: true,
includePaths: ['src/styles'],
// Stencil-specific: inject global Sass files
injectGlobalPaths: ['src/styles/variables.scss', 'src/styles/mixins.scss']
})
]
};Creates and configures the Stencil Sass plugin for processing .scss and .sass files.
/**
* Creates and configures the Stencil Sass plugin
* @param opts - Optional configuration options for the plugin
* @returns Configured Stencil plugin with transform method
*/
function sass(opts?: PluginOptions): Plugin;The plugin automatically:
.scss and .sass extensions (case insensitive)Usage Examples:
// Minimal configuration
sass()
// Basic configuration with output options
sass({
outputStyle: 'compressed',
sourceMap: true
})
// Advanced configuration with global injection
sass({
includePaths: ['src/styles', 'node_modules'],
injectGlobalPaths: [
'src/styles/variables.scss',
'src/styles/mixins.scss'
],
outputStyle: 'expanded',
sourceMap: true,
quietDeps: true
})interface PluginOptions {
/** Path to a file to compile */
file?: string;
/** A string to pass to compile (use with includePaths for @import support) */
data?: string;
/** Custom importer functions for handling @import directives */
importer?: Importer | Importer[];
/** Custom functions that may be invoked by Sass files */
functions?: { [key: string]: (...args: any[]) => any };
/** Paths for @import resolution */
includePaths?: string[];
/** Global Sass files to inject (Stencil-specific feature) */
injectGlobalPaths?: string[];
/** Enable Sass indented syntax for parsing */
indentedSyntax?: boolean;
/** Indentation character type */
indentType?: 'space' | 'tab';
/** Number of spaces/tabs for indentation */
indentWidth?: number;
/** Line break sequence */
linefeed?: 'cr' | 'crlf' | 'lf' | 'lfcr';
/** Disable source map URL inclusion in output */
omitSourceMapUrl?: boolean;
/** Output file location for source maps */
outFile?: string;
/** CSS output format */
outputStyle?: 'compressed' | 'expanded';
/** Suppress dependency warnings */
quietDeps?: boolean;
/** Silence specific deprecation warnings */
silenceDeprecations?: DeprecationOrId[];
/** Enable source map generation */
sourceMap?: boolean | string;
/** Include contents in source map */
sourceMapContents?: boolean;
/** Embed source map as data URI */
sourceMapEmbed?: boolean;
/** Source map root value */
sourceMapRoot?: string;
}Support for custom importer functions to extend Sass import handling.
/**
* Function type for custom Sass importers
* @param url - The URL/path being imported
* @param prev - The stylesheet that contained the @import
* @param done - Callback to return the import result
* @returns Import result or void (for async handling via callback)
*/
type Importer = (
url: string,
prev: string,
done: (data: ImporterReturnType) => void
) => ImporterReturnType | void;
/**
* Return type for importer functions
*/
type ImporterReturnType =
| { file: string } // Return file path to load
| { contents: string } // Return contents directly
| Error // Return error
| null; // Unable to handle this importUsage Example:
sass({
importer: [
// Custom importer for special prefixes
(url, prev, done) => {
if (url.startsWith('theme:')) {
const themePath = `src/themes/${url.substring(6)}.scss`;
done({ file: themePath });
return;
}
done(null); // Let default importer handle it
}
]
})The injectGlobalPaths option automatically injects Sass files at the beginning of each processed file:
sass({
injectGlobalPaths: [
'src/styles/variables.scss',
'src/styles/mixins.scss'
]
})This makes variables and mixins available in all component stylesheets without manual imports.
The plugin automatically handles tilde (~) imports for resolving modules from node_modules:
// Import from node_modules
@import '~bootstrap/scss/variables';
@import '~@angular/material/theming';.scss - Sass SCSS syntax (default).sass - Sass indented syntax (automatically detected)Comprehensive error reporting with:
Full source map support for debugging:
Optimized for debugging and development workflow:
sass({
// Expanded output for easier CSS debugging
outputStyle: 'expanded',
// Enable source maps with full content for debugging
sourceMap: true,
sourceMapContents: true,
// Include both project styles and node_modules for imports
includePaths: ['src/styles', 'node_modules'],
// Inject development-specific variables
injectGlobalPaths: ['src/styles/dev-variables.scss']
})Optimized for bundle size and performance:
sass({
// Compressed output for smaller CSS bundles
outputStyle: 'compressed',
// Disable source maps in production
sourceMap: false,
// Suppress dependency warnings to reduce noise
quietDeps: true,
// Silence legacy API deprecation warnings
silenceDeprecations: ['legacy-js-api'],
// Only include necessary paths
includePaths: ['src/styles'],
// Inject only production variables and mixins
injectGlobalPaths: ['src/styles/variables.scss', 'src/styles/mixins.scss']
})sass({
functions: {
'get-theme-color($name)': (name: any) => {
const colors = {
primary: '#007bff',
secondary: '#6c757d'
};
return colors[name.getValue()] || '#000000';
}
}
})/**
* Stencil plugin interface (re-exported from @stencil/core)
*/
interface Plugin {
name: string;
pluginType: string;
transform?: (sourceText: string, fileName: string, context: PluginCtx) => Promise<PluginTransformResults>;
}
/**
* Plugin transformation results
*/
interface PluginTransformResults {
id: string;
code?: string;
dependencies?: string[];
}
/**
* Plugin context provided by Stencil
*/
interface PluginCtx {
config: Config;
fs: FileSystem;
sys: System;
diagnostics: Diagnostic[];
}
/**
* Deprecation identifier type from sass-embedded
*/
type DeprecationOrId = string | { id: string };Note: The plugin re-exports all types from @stencil/core/internal, making them available for TypeScript users who need to work with the plugin API directly.