or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-stylus-loader

Webpack loader for compiling Stylus CSS preprocessor files into regular CSS

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/stylus-loader@8.1.x

To install, run

npx @tessl/cli install tessl/npm-stylus-loader@8.1.0

index.mddocs/

stylus-loader

stylus-loader is a webpack loader that compiles Stylus CSS preprocessor files into regular CSS. It provides comprehensive webpack integration with configurable options for Stylus compilation, import resolution, source maps, and plugin support.

Package Information

  • Package Name: stylus-loader
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install stylus stylus-loader --save-dev

Core Imports

stylus-loader is a webpack loader, so it's not imported directly in your application code. Instead, it's configured in your webpack configuration:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          "style-loader",
          "css-loader", 
          "stylus-loader"
        ]
      }
    ]
  }
};

For custom configuration:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "stylus-loader",
            options: {
              stylusOptions: {
                use: ["nib"],
                compress: true
              }
            }
          }
        ]
      }
    ]
  }
};

Basic Usage

  1. Install the required dependencies:
npm install stylus stylus-loader css-loader style-loader --save-dev
  1. Configure webpack to use stylus-loader:
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          "style-loader",    // creates style nodes from JS strings
          "css-loader",      // translates CSS into CommonJS
          "stylus-loader"    // compiles Stylus to CSS
        ]
      }
    ]
  }
};
  1. Create and import Stylus files:
// styles.styl
$primary = #ff6b6b
$secondary = #4ecdc4

.header
  background-color $primary
  color white
  padding 20px
// app.js
import './styles.styl';

Architecture

stylus-loader implements a webpack-integrated Stylus compilation pipeline with several key components:

  • Loader Function: Main async webpack loader that orchestrates the compilation process
  • Stylus Integration: Direct integration with the Stylus compiler API, supporting all Stylus options
  • Webpack Importer: Custom import resolver that enables webpack-style module resolution (@import from node_modules)
  • Source Map Processing: Advanced source map generation and normalization for debugging support
  • Dependency Tracking: Automatic dependency tracking for webpack's watch mode and incremental builds
  • Error Handling: Comprehensive error reporting with file locations and webpack-compatible error formatting

The compilation flow:

  1. Receives Stylus source code from webpack
  2. Applies additionalData preprocessing if configured
  3. Creates Stylus compiler instance with merged options
  4. Configures webpack import resolver for node_modules support
  5. Processes imports, includes, and dependencies
  6. Compiles Stylus to CSS with source maps
  7. Tracks all file dependencies for webpack watch mode
  8. Returns compiled CSS and source maps to webpack

This architecture enables seamless integration with webpack's module system while preserving all Stylus features and providing robust development tooling support.

Capabilities

Loader Configuration

Configure stylus-loader behavior through webpack options.

interface LoaderOptions {
  implementation?: string | Function;
  stylusOptions?: StylusOptions | ((loaderContext: LoaderContext) => StylusOptions);
  sourceMap?: boolean;
  webpackImporter?: boolean;
  additionalData?: string | ((content: string, loaderContext: LoaderContext) => string | Promise<string>);
}

Usage Example:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "stylus-loader",
            options: {
              stylusOptions: {
                use: ["nib"],
                compress: true,
                lineNumbers: true
              },
              sourceMap: true,
              additionalData: `@env: ${process.env.NODE_ENV};`
            }
          }
        ]
      }
    ]
  }
};

Stylus Options Configuration

Configure the underlying Stylus compiler through stylusOptions.

interface StylusOptions {
  use?: (string | Function)[];
  include?: string[];
  import?: string[];
  define?: any[] | { [key: string]: any };
  includeCSS?: boolean;
  resolveURL?: boolean | URLResolverOptions;
  lineNumbers?: boolean;
  hoistAtrules?: boolean;
  compress?: boolean;
  disableCache?: boolean;
  sourcemap?: boolean | SourceMapOptions;
  paths?: string[];
}

interface URLResolverOptions {
  nocheck?: boolean;
  paths?: string[];
}

interface SourceMapOptions {
  comment?: boolean;
  sourceRoot?: string;
  basePath?: string;
}

Usage Example:

// webpack.config.js with comprehensive Stylus options
{
  loader: "stylus-loader",
  options: {
    stylusOptions: {
      // Use Stylus plugins (can be strings or functions)
      use: ["nib", require("autoprefixer-stylus")()],
      
      // Additional include paths for imports
      include: [path.join(__dirname, "src/styles")],
      
      // Files to automatically import
      import: ["nib", "variables.styl"],
      
      // Define variables (recommended array syntax)
      define: [
        ["$development", process.env.NODE_ENV === "development"],
        ["$version", JSON.stringify(require("./package.json").version)]
      ],
      
      // Include regular CSS on @import
      includeCSS: false,
      
      // Resolve relative url()'s inside imported files
      resolveURL: true,
      
      // Emit line number comments in generated CSS
      lineNumbers: true,
      
      // Move @import and @charset to the top
      hoistAtrules: true,
      
      // Compress CSS output (auto-enabled in production)
      compress: process.env.NODE_ENV === "production",
      
      // Disable Stylus caching for faster rebuilds in development
      disableCache: process.env.NODE_ENV === "development"
    }
  }
}

Source Map Support

Enable source map generation for debugging compiled Stylus code.

interface SourceMapConfiguration {
  sourceMap?: boolean;
}

Usage Example:

// webpack.config.js with source maps
module.exports = {
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: { sourceMap: true }
          },
          {
            loader: "stylus-loader",
            options: { sourceMap: true }
          }
        ]
      }
    ]
  }
};

Webpack Import Resolution

Control webpack-style import resolution for Stylus files.

interface WebpackImporterConfiguration {
  webpackImporter?: boolean;
}

With webpack importer enabled (default), you can import from node_modules:

@import "bootstrap-styl/bootstrap/index.styl"
@import "~package-name/styles.styl"  // ~ prefix (legacy, still supported)

Usage Example:

// Disable webpack importer for performance
{
  loader: "stylus-loader",
  options: {
    webpackImporter: false  // Use only Stylus native resolution
  }
}

Additional Data Injection

Prepend data to Stylus files before compilation.

interface AdditionalDataConfiguration {
  additionalData?: string | AdditionalDataFunction;
}

type AdditionalDataFunction = (
  content: string,
  loaderContext: LoaderContext
) => string | Promise<string>;

interface LoaderContext {
  resourcePath: string;
  rootContext: string;
  // ... other webpack loader context properties
}

Usage Examples:

// String injection
{
  loader: "stylus-loader",
  options: {
    additionalData: `@env: ${process.env.NODE_ENV};`
  }
}

// Function injection (sync)
{
  loader: "stylus-loader",
  options: {
    additionalData: (content, loaderContext) => {
      const { resourcePath, rootContext } = loaderContext;
      const relativePath = path.relative(rootContext, resourcePath);
      
      if (relativePath.includes("admin")) {
        return `@theme: admin;\n${content}`;
      }
      return `@theme: default;\n${content}`;
    }
  }
}

// Function injection (async)
{
  loader: "stylus-loader",
  options: {
    additionalData: async (content, loaderContext) => {
      const config = await loadConfig();
      return `@config: ${JSON.stringify(config)};\n${content}`;
    }
  }
}

Custom Stylus Implementation

Specify a custom Stylus implementation instead of the default.

interface ImplementationConfiguration {
  implementation?: string | Function;
}

Usage Examples:

// Use specific Stylus version by package name
{
  loader: "stylus-loader",
  options: {
    implementation: "stylus"  // or "stylus-legacy", etc.
  }
}

// Use specific Stylus instance
{
  loader: "stylus-loader",
  options: {
    implementation: require("stylus")
  }
}

// Use resolved path
{
  loader: "stylus-loader",
  options: {
    implementation: require.resolve("stylus")
  }
}

Advanced Usage Patterns

Using with Stylus Plugins

// webpack.config.js with nib plugin
{
  loader: "stylus-loader",
  options: {
    stylusOptions: {
      use: [require("nib")()],
      import: ["nib"]
    }
  }
}
// Now you can use nib mixins
.box
  border-radius 5px
  gradient #fff #000

Dynamic Configuration Based on Environment

// webpack.config.js with environment-based config
{
  loader: "stylus-loader",  
  options: {
    stylusOptions: (loaderContext) => {
      const isDev = loaderContext.mode === "development";
      return {
        compress: !isDev,
        lineNumbers: isDev,
        sourcemap: isDev,
        use: isDev ? [] : ["autoprefixer-stylus"]
      };
    }
  }
}

Import Resolution with Paths

// webpack.config.js with custom import paths
{
  loader: "stylus-loader",
  options: {
    stylusOptions: {
      paths: [
        path.resolve(__dirname, "src/styles"),
        path.resolve(__dirname, "node_modules")
      ]
    }
  }
}
// Can now import from configured paths
@import "variables"     // resolves to src/styles/variables.styl
@import "bootstrap"     // resolves from node_modules

Glob Pattern Imports

// Import multiple files with glob patterns
@import "components/**/*.styl"
@import "mixins/*.styl"

Common Configuration Examples

Development Configuration

// webpack.config.js for development
{
  loader: "stylus-loader",
  options: {
    sourceMap: true,
    stylusOptions: {
      lineNumbers: true,
      compress: false,
      sourcemap: {
        comment: true
      }
    }
  }
}

Production Configuration

// webpack.config.js for production
{
  loader: "stylus-loader",
  options: {
    stylusOptions: {
      compress: true,
      hoistAtrules: true,
      resolveURL: true
    }
  }
}

Library Development Configuration

// webpack.config.js for library development
{
  loader: "stylus-loader",
  options: {
    stylusOptions: {
      use: ["nib"],
      include: [path.resolve(__dirname, "src/lib")],
      define: [
        ["$library-version", JSON.stringify(require("./package.json").version)]
      ]
    }
  }
}

Error Handling

stylus-loader provides detailed error messages for common issues:

  • Stylus Compilation Errors: Syntax errors in Stylus files with file location and line numbers
  • Import Resolution Errors: Missing files or incorrect import paths, including module resolution failures
  • Plugin Loading Errors: Issues loading Stylus plugins specified in use option via require.resolve()
  • Implementation Errors: Problems with custom Stylus implementation (e.g., "The Stylus implementation 'xyz' not found")
  • Glob Resolution Errors: Invalid glob patterns in imports (e.g., "Glob resolving without a glob base is not supported")
  • File System Errors: Issues reading imported files or source maps during compilation
  • Parser Errors: Stylus AST parsing errors that prevent dependency analysis

Errors include webpack-style error reporting with:

  • File paths and line numbers for precise error location
  • Detailed error descriptions with context
  • Automatic dependency tracking for failed imports
  • Stack trace preservation from underlying Stylus compiler
  • Resolution suggestions where applicable

Common error scenarios:

  • Missing @import files: Check file paths and ensure files exist
  • Plugin loading failures: Verify plugin names and installation
  • Glob import issues: Use proper glob base syntax (~package/**/* not ~**/*)
  • Custom implementation not found: Ensure implementation package is installed

Version Compatibility

  • Node.js: >= 18.12.0
  • webpack: ^5.0.0
  • Stylus: >= 0.52.4
  • @rspack/core: 0.x || 1.x (optional alternative to webpack)

Types

interface LoaderContext {
  resourcePath: string;
  rootContext: string;
  mode: string;
  sourceMap: boolean;
  getOptions: (schema?: object) => LoaderOptions;
  async: () => (error: Error | null, content?: string, sourceMap?: object) => void;
  addDependency: (file: string) => void;
  addContextDependency: (context: string) => void;
  addBuildDependency: (file: string) => void;
  emitError: (error: Error) => void;
  fs: object;
}

interface LoaderOptions {
  implementation?: string | Function;
  stylusOptions?: StylusOptions | ((loaderContext: LoaderContext) => StylusOptions);
  sourceMap?: boolean;
  webpackImporter?: boolean;
  additionalData?: string | ((content: string, loaderContext: LoaderContext) => string | Promise<string>);
}

interface StylusOptions {
  use?: (string | Function)[];
  include?: string[];
  import?: string[];
  define?: any[] | { [key: string]: any };
  includeCSS?: boolean;
  resolveURL?: boolean | URLResolverOptions;
  lineNumbers?: boolean;
  hoistAtrules?: boolean;
  compress?: boolean;
  disableCache?: boolean;
  sourcemap?: boolean | SourceMapOptions;
  paths?: string[];
  filename?: string;
  dest?: string;
}

interface URLResolverOptions {
  nocheck?: boolean;
  paths?: string[];
}

interface SourceMapOptions {
  comment?: boolean;
  sourceRoot?: string;
  basePath?: string;
}