or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-postcss-less

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/postcss-less@6.0.x

To install, run

npx @tessl/cli install tessl/npm-postcss-less@6.0.0

0

# postcss-less

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: postcss-less

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install postcss-less`

10

- **Node.js Version**: >=12

11

- **Peer Dependencies**: `postcss ^8.3.5`

12

13

## Core Imports

14

15

```javascript

16

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

17

```

18

19

For ES6 modules:

20

21

```javascript

22

import syntax from 'postcss-less';

23

```

24

25

Individual imports:

26

27

```javascript

28

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

29

```

30

31

## Basic Usage

32

33

```javascript

34

const postcss = require('postcss');

35

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

36

37

// Parse LESS code with PostCSS

38

const lessCode = `

39

// This is an inline comment

40

@primary-color: #428bca;

41

@secondary-color: lighten(@primary-color, 20%);

42

43

.header {

44

color: @primary-color;

45

.nav {

46

background: @secondary-color;

47

}

48

}

49

50

.mixin-example() {

51

border-radius: 4px;

52

}

53

54

.button {

55

.mixin-example();

56

&:hover {

57

color: darken(@primary-color, 10%);

58

}

59

}

60

`;

61

62

// Process with PostCSS and postcss-less syntax

63

postcss([

64

// Add your PostCSS plugins here

65

])

66

.process(lessCode, { syntax })

67

.then(function (result) {

68

console.log(result.css); // Processed LESS code

69

});

70

```

71

72

## Architecture

73

74

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

75

76

- **LessParser**: Extends PostCSS Parser to recognize LESS constructs (variables, mixins, inline comments, imports with options)

77

- **LessStringifier**: Extends PostCSS Stringifier to output LESS syntax correctly

78

- **Node Handlers**: Specialized processors for different LESS node types (imports, variables, mixins, inline comments, interpolation)

79

- **AST Extensions**: Adds LESS-specific properties to PostCSS AST nodes for semantic information

80

81

## Capabilities

82

83

### LESS Parsing

84

85

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

86

87

```javascript { .api }

88

/**

89

* Parse LESS source code into PostCSS AST

90

* @param {string} less - LESS source code to parse

91

* @param {Object} options - PostCSS Input options (from, map, etc.)

92

* @returns {Root} PostCSS Root AST node with LESS-specific extensions

93

*/

94

function parse(less, options);

95

```

96

97

**Usage Example:**

98

99

```javascript

100

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

101

102

const lessCode = '@color: red; .test { color: @color; }';

103

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

104

105

// Access LESS-specific node properties

106

root.walkAtRules((rule) => {

107

if (rule.variable) {

108

console.log(`Variable: ${rule.name} = ${rule.value}`);

109

}

110

});

111

```

112

113

### LESS Stringification

114

115

Convert PostCSS AST nodes back to LESS syntax strings.

116

117

```javascript { .api }

118

/**

119

* Convert PostCSS AST nodes to LESS syntax strings

120

* @param {Node} node - PostCSS AST node to stringify

121

* @param {Function} builder - String builder callback function

122

*/

123

function stringify(node, builder);

124

```

125

126

**Usage Example:**

127

128

```javascript

129

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

130

131

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

132

const root = syntax.parse(lessCode);

133

134

syntax.stringify(root, (str) => {

135

process.stdout.write(str);

136

});

137

```

138

139

### Node String Conversion

140

141

Convert individual AST nodes to their string representation.

142

143

```javascript { .api }

144

/**

145

* Convert a single AST node to its string representation

146

* @param {Node} node - PostCSS AST node to convert

147

* @returns {string} String representation of the node

148

*/

149

function nodeToString(node);

150

```

151

152

**Usage Example:**

153

154

```javascript

155

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

156

157

const lessCode = '@var: 10px; .test { margin: @var; }';

158

const root = syntax.parse(lessCode);

159

160

root.walkAtRules((rule) => {

161

if (rule.variable) {

162

const nodeStr = syntax.nodeToString(rule);

163

console.log(`Variable node: ${nodeStr}`);

164

}

165

});

166

```

167

168

## LESS-Specific Features

169

170

### Variable Support

171

172

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

173

174

```javascript { .api }

175

// Variable AtRule node properties

176

interface VariableAtRule extends AtRule {

177

variable: true; // Marks node as LESS variable

178

name: string; // Variable name (without @)

179

value: string; // Variable value

180

}

181

```

182

183

### Import Support

184

185

LESS `@import` statements with options are supported:

186

187

```javascript { .api }

188

// Import AtRule node properties

189

interface ImportAtRule extends AtRule {

190

import: true; // Marks node as import

191

filename: string; // Imported filename

192

options?: string; // Import options (reference, inline, etc.)

193

}

194

```

195

196

**Example:**

197

```less

198

@import (reference) "variables.less";

199

@import "mixins.less";

200

```

201

202

### Mixin Support

203

204

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

205

206

```javascript { .api }

207

// Mixin AtRule node properties

208

interface MixinAtRule extends AtRule {

209

mixin: true; // Marks node as mixin call

210

important?: true; // Present if mixin uses !important

211

}

212

```

213

214

### Function Support

215

216

LESS `each` functions and other function calls are supported:

217

218

```javascript { .api }

219

// Function AtRule node properties

220

interface FunctionAtRule extends AtRule {

221

function: true; // Marks node as function call

222

params: string; // Function parameters

223

}

224

```

225

226

**Example:**

227

```less

228

each(@list, {

229

.column-@{value} {

230

width: 100% / @length;

231

}

232

});

233

```

234

235

### Interpolation Support

236

237

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

238

239

### Inline Comment Support

240

241

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

242

243

```javascript { .api }

244

// Inline Comment node properties

245

interface InlineComment extends Comment {

246

inline: true; // Marks comment as inline

247

raws: {

248

begin: '//'; // Comment delimiter

249

left: string; // Whitespace before text

250

right: string; // Whitespace after text

251

};

252

}

253

```

254

255

### Extend Support

256

257

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

258

259

```javascript { .api }

260

// Extend Rule/Declaration properties

261

interface ExtendNode extends Rule | Declaration {

262

extend: true; // Marks node as using extend

263

}

264

```

265

266

## Error Handling

267

268

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

269

270

```javascript

271

const postcss = require('postcss');

272

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

273

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

274

275

try {

276

const result = await postcss().process('.@{]', { syntax });

277

} catch (error) {

278

if (error instanceof CssSyntaxError) {

279

console.log(`Parse error at line ${error.line}, column ${error.column}: ${error.message}`);

280

}

281

}

282

```

283

284

## PostCSS Integration

285

286

Use as a syntax plugin with PostCSS processors:

287

288

```javascript

289

const postcss = require('postcss');

290

const autoprefixer = require('autoprefixer');

291

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

292

293

// Apply autoprefixer to LESS code

294

postcss([autoprefixer])

295

.process(lessCode, {

296

syntax,

297

from: 'input.less',

298

to: 'output.less'

299

})

300

.then(result => {

301

console.log(result.css); // LESS code with vendor prefixes

302

});

303

```

304

305

## Types

306

307

```javascript { .api }

308

// Main syntax object

309

interface PostcssLessSyntax {

310

parse: (less: string, options?: ProcessOptions) => Root;

311

stringify: (node: Node, builder: (str: string) => void) => void;

312

nodeToString: (node: Node) => string;

313

}

314

315

// PostCSS types (from postcss package)

316

interface ProcessOptions {

317

from?: string;

318

to?: string;

319

map?: SourceMapOptions | boolean;

320

parser?: Parser;

321

stringifier?: Stringifier;

322

}

323

324

interface Root extends Container {

325

type: 'root';

326

walk(callback: (node: Node) => boolean | void): Root;

327

walkAtRules(callback: (atRule: AtRule) => boolean | void): Root;

328

walkComments(callback: (comment: Comment) => boolean | void): Root;

329

walkDecls(callback: (decl: Declaration) => boolean | void): Root;

330

walkRules(callback: (rule: Rule) => boolean | void): Root;

331

}

332

333

interface AtRule extends Container {

334

type: 'atrule';

335

name: string;

336

params: string;

337

// LESS extensions

338

import?: boolean;

339

filename?: string;

340

options?: string;

341

variable?: boolean;

342

value?: string;

343

mixin?: boolean;

344

function?: boolean;

345

important?: boolean;

346

}

347

348

interface Comment extends Node {

349

type: 'comment';

350

text: string;

351

// LESS extensions

352

inline?: boolean;

353

}

354

355

interface Rule extends Container {

356

type: 'rule';

357

selector: string;

358

// LESS extensions

359

extend?: boolean;

360

}

361

362

interface Declaration extends Node {

363

type: 'decl';

364

prop: string;

365

value: string;

366

// LESS extensions

367

extend?: boolean;

368

}

369

```