CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-postcss-less

LESS parser for PostCSS that enables PostCSS transformations and plugins to work directly with LESS source code without compilation.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

postcss-less

postcss-less is a PostCSS syntax parser specifically designed for LESS stylesheets. It enables PostCSS transformations and plugins to work directly with LESS source code without compilation, serving as a bridge between LESS syntax and the PostCSS ecosystem.

Package Information

  • Package Name: postcss-less
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install postcss-less
  • Node.js Version: >=12
  • Peer Dependencies: postcss ^8.3.5

Core Imports

const syntax = require('postcss-less');

For ES6 modules:

import syntax from 'postcss-less';

Individual imports:

const { parse, stringify, nodeToString } = require('postcss-less');

Basic Usage

const postcss = require('postcss');
const syntax = require('postcss-less');

// Parse LESS code with PostCSS
const lessCode = `
// This is an inline comment
@primary-color: #428bca;
@secondary-color: lighten(@primary-color, 20%);

.header {
  color: @primary-color;
  .nav {
    background: @secondary-color;
  }
}

.mixin-example() {
  border-radius: 4px;
}

.button {
  .mixin-example();
  &:hover {
    color: darken(@primary-color, 10%);
  }
}
`;

// Process with PostCSS and postcss-less syntax
postcss([
  // Add your PostCSS plugins here
])
  .process(lessCode, { syntax })
  .then(function (result) {
    console.log(result.css); // Processed LESS code
  });

Architecture

postcss-less extends the PostCSS parser and stringifier to handle LESS-specific syntax:

  • LessParser: Extends PostCSS Parser to recognize LESS constructs (variables, mixins, inline comments, imports with options)
  • LessStringifier: Extends PostCSS Stringifier to output LESS syntax correctly
  • Node Handlers: Specialized processors for different LESS node types (imports, variables, mixins, inline comments, interpolation)
  • AST Extensions: Adds LESS-specific properties to PostCSS AST nodes for semantic information

Capabilities

LESS Parsing

Parse LESS source code into a PostCSS-compatible AST with LESS-specific node properties.

/**
 * Parse LESS source code into PostCSS AST
 * @param {string} less - LESS source code to parse
 * @param {Object} options - PostCSS Input options (from, map, etc.)
 * @returns {Root} PostCSS Root AST node with LESS-specific extensions
 */
function parse(less, options);

Usage Example:

const syntax = require('postcss-less');

const lessCode = '@color: red; .test { color: @color; }';
const root = syntax.parse(lessCode, { from: 'input.less' });

// Access LESS-specific node properties
root.walkAtRules((rule) => {
  if (rule.variable) {
    console.log(`Variable: ${rule.name} = ${rule.value}`);
  }
});

LESS Stringification

Convert PostCSS AST nodes back to LESS syntax strings.

/**
 * Convert PostCSS AST nodes to LESS syntax strings
 * @param {Node} node - PostCSS AST node to stringify  
 * @param {Function} builder - String builder callback function
 */
function stringify(node, builder);

Usage Example:

const syntax = require('postcss-less');

const lessCode = '.mixin() { color: red; }';
const root = syntax.parse(lessCode);

syntax.stringify(root, (str) => {
  process.stdout.write(str);
});

Node String Conversion

Convert individual AST nodes to their string representation.

/**
 * Convert a single AST node to its string representation
 * @param {Node} node - PostCSS AST node to convert
 * @returns {string} String representation of the node
 */
function nodeToString(node);

Usage Example:

const syntax = require('postcss-less');

const lessCode = '@var: 10px; .test { margin: @var; }';
const root = syntax.parse(lessCode);

root.walkAtRules((rule) => {
  if (rule.variable) {
    const nodeStr = syntax.nodeToString(rule);
    console.log(`Variable node: ${nodeStr}`);
  }
});

LESS-Specific Features

Variable Support

LESS variables (@variable-name: value;) are parsed with special properties:

// Variable AtRule node properties
interface VariableAtRule extends AtRule {
  variable: true;      // Marks node as LESS variable
  name: string;        // Variable name (without @)
  value: string;       // Variable value
}

Import Support

LESS @import statements with options are supported:

// Import AtRule node properties  
interface ImportAtRule extends AtRule {
  import: true;        // Marks node as import
  filename: string;    // Imported filename
  options?: string;    // Import options (reference, inline, etc.)
}

Example:

@import (reference) "variables.less";
@import "mixins.less";

Mixin Support

LESS mixins (.mixin() and #mixin) are parsed with special properties:

// Mixin AtRule node properties
interface MixinAtRule extends AtRule {
  mixin: true;         // Marks node as mixin call
  important?: true;    // Present if mixin uses !important
}

Function Support

LESS each functions and other function calls are supported:

// Function AtRule node properties
interface FunctionAtRule extends AtRule {
  function: true;      // Marks node as function call
  params: string;      // Function parameters
}

Example:

each(@list, {
  .column-@{value} {
    width: 100% / @length;
  }
});

Interpolation Support

LESS variable interpolation (@{variable}) is processed during parsing to handle dynamic property names and values.

Inline Comment Support

Double-slash comments (//) are supported with special properties:

// Inline Comment node properties
interface InlineComment extends Comment {
  inline: true;        // Marks comment as inline
  raws: {
    begin: '//';       // Comment delimiter
    left: string;      // Whitespace before text
    right: string;     // Whitespace after text
  };
}

Extend Support

LESS :extend() syntax is recognized on both rules and declarations:

// Extend Rule/Declaration properties
interface ExtendNode extends Rule | Declaration {
  extend: true;        // Marks node as using extend
}

Error Handling

postcss-less follows PostCSS error handling patterns. Parse errors throw CssSyntaxError:

const postcss = require('postcss');
const syntax = require('postcss-less');
const CssSyntaxError = require('postcss/lib/css-syntax-error');

try {
  const result = await postcss().process('.@{]', { syntax });
} catch (error) {
  if (error instanceof CssSyntaxError) {
    console.log(`Parse error at line ${error.line}, column ${error.column}: ${error.message}`);
  }
}

PostCSS Integration

Use as a syntax plugin with PostCSS processors:

const postcss = require('postcss');
const autoprefixer = require('autoprefixer');
const syntax = require('postcss-less');

// Apply autoprefixer to LESS code
postcss([autoprefixer])
  .process(lessCode, { 
    syntax,
    from: 'input.less',
    to: 'output.less'
  })
  .then(result => {
    console.log(result.css); // LESS code with vendor prefixes
  });

Types

// Main syntax object
interface PostcssLessSyntax {
  parse: (less: string, options?: ProcessOptions) => Root;
  stringify: (node: Node, builder: (str: string) => void) => void;
  nodeToString: (node: Node) => string;
}

// PostCSS types (from postcss package)
interface ProcessOptions {
  from?: string;
  to?: string;
  map?: SourceMapOptions | boolean;
  parser?: Parser;
  stringifier?: Stringifier;
}

interface Root extends Container {
  type: 'root';
  walk(callback: (node: Node) => boolean | void): Root;
  walkAtRules(callback: (atRule: AtRule) => boolean | void): Root;
  walkComments(callback: (comment: Comment) => boolean | void): Root;
  walkDecls(callback: (decl: Declaration) => boolean | void): Root;
  walkRules(callback: (rule: Rule) => boolean | void): Root;
}

interface AtRule extends Container {
  type: 'atrule';
  name: string;
  params: string;
  // LESS extensions
  import?: boolean;
  filename?: string;
  options?: string;
  variable?: boolean;
  value?: string;
  mixin?: boolean;
  function?: boolean;
  important?: boolean;
}

interface Comment extends Node {
  type: 'comment';
  text: string;
  // LESS extensions
  inline?: boolean;
}

interface Rule extends Container {
  type: 'rule';
  selector: string;
  // LESS extensions
  extend?: boolean;
}

interface Declaration extends Node {
  type: 'decl';
  prop: string;
  value: string;
  // LESS extensions
  extend?: boolean;
}

Install with Tessl CLI

npx tessl i tessl/npm-postcss-less
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/postcss-less@6.0.x
Publish Source
CLI
Badge
tessl/npm-postcss-less badge