Easily work with LESS files in Visual Studio Code.
"Compile-on-save" for LESS stylesheets without using a build task.
Generates a .css
file each time you save a .less
file.
e.g. styles.less
--> styles.css
Compile errors integrate with the standard Errors and Warnings list.
Has reasonable default settings, but...
Configurable, as needed:
autoprefixer plugin included.
.less
file in the project..css
file is output to the same directory as the source .less
file..css.map
files) are not output..less
file..css
file is automatically generated.N.B. Also available from the command palette as "Compile LESS to CSS".
settings.json
file (i.e. Workspace Settings).settings.json
must exist in the .vscode
directory at the root level of your project."less.compile"
key.settings.json
file:
{
"less.compile": {
"compress": true, // true => remove surplus whitespace
"sourceMap": true, // true => generate source maps (.css.map files)
"out": false // false => DON'T output .css files (overridable per-file, see below)
}
}
.less
file as a comment on the first line.Example:
// out: "../dist/app.css", compress: true, sourceMap: false
body,
html {
...;
}
main: { filepath: string | string[] }
out: { boolean | filepath: string | folderpath: string }
filepath
is used, but no file extension is specified, it will append .css
folderpath
is used, the less filename will be used, but with the .css
extension/
(or \
for Windows), e.g. ../css/
not ../css
(the latter is always interpreted as an extensionless filename).../../styles.css
${workspaceFolder}
— the root folder for the VS Code project containing the .less
file.$1
— the "base" name of the .less
file, e.g. for styles.css
, $1
would be style
.$2
— the extension of the css file, usually .css
unless outExt
is used.${workspaceFolder}/dist/css/final-$1$2
out: false
= don't output."out": false
setting, where you only want certain .less
files to be generated.outExt: { string }
.css
..wxss
instead of .css
).map
file also (e.g. .wxss.map
)sourceMap: { boolean }
.css.map
file will be output in the same direction as the .css
file (except when sourceMapFileInline
is set, see below).out
setting is respected.sourceMapFileInline: { boolean }
.css
file outputted will contain an inline source-map.compress: { boolean }
relativeUrls: { boolean }
@import
'ed should be rewritten relative to the importing file.out
parameter.Example of true
option—given this folder structure:
/main.less
/css/feature/feature.less
/css/feature/background.png
/main.less:
// relativeUrls: true
@import 'css/feature/feature.less';
/css/feature/features.less:
// main: "../../main.less"
.feature {
background-image: url(background.png);
}
/main.css: (output)
.feature {
background-image: url('css/feature/background.png');
}
autoprefixer: { string | string[] }
When present, this enables the autoprefixer plugin for less (included).
This plugin automatically adds/removes vendor-prefixes needed to support a set of browsers which you specify.
The autoprefixer
option is the comma-separated list of browsers
for autoprefixer to use (or alternatively a string array of them).
Example of autoprefixer
within .vscode/settings.json
:
{
"less.compile": {
"autoprefixer": "> 5%, last 2 Chrome versions, not ie 6-9"
}
}
See browserslist documentation for further examples of browser queries.
NOTE: If used with the per-file configuration, the browsers listed must be semi-colon separated (because comma is already the directive separator): e.g.
// autoprefixer: "> 5%; last 2 Chrome versions; not ie 6-9", sourceMap: true, out: "../css/style.css"
ieCompat: { boolean }
true
).true
: prevents inlining of data-uri
s that exceed 32KB.false
: removes restriction on data-uri
size.javascriptEnabled: { boolean }
false
).font-weight: `10+10`px';
math: { "parens-division" | "parens" | "always" | "strict" | "strict-legacy" }
math
option used by the less compiler."parens-division"
in less v4.0.0 (and consequently in Easy LESS v1.7.0)"parens-division"
.{
"less.compile": {
"math": "always"
}
}
... or, using a per-file directive:
// math: "always"
Alternatively, you can wrap your expression in parentheses:
.w-third {
width: (100% / 3);
}
Settings are read and applied in the following order:
settings.json
(aka Workspace Settings)How do I redirect the output to a separate file?
Add the following line to the head of your less file:
// out: "new-file.css"
How do I redirect all css output to a specific folder?
Specify the out parameter in the
settings.json
file, as a relative or absolute path, with a trailing slash (/
or\\
).Tip: You can use the environment variable
${workspaceRoot}
to specify paths relative to the workspace:
.vscode/settings.json
:{ "less.compile": { "out": "${workspaceRoot}\\css\\" } }
How do I suppress compiling this less file / compile a different less file than the one being edited?
Add a reference to the master.less file to the head of the imported less file:
// main: "master.less"
How do I suppress the compilation of a single less file?
Set
out
to false (or null) in a comment at the top of the .less file:// out: false
How do I compile only some of the .less files in my project?
a. Default
"out"
setting to false insettings.json
b. Overrideout
for each.less
file that you want to compile:
.vscode/settings.json
:{ "less.compile": { "out": false } }
style.less
: (will be compiled tostyle.css
)// out: true @import 'mixins.less'; body, html { ...; }
mixins.less
: (no comment line, will not be compiled).border-radius(@radius) { -webkit-border-radius: @radius; -moz-border-radius: @radius; -ms-border-radius: @radius; border-radius: @radius; }
Is it possible to have multiple "main" .less files?
Yes, multiple main files can be specified in these ways:
In settings.json, using a string array:
.vscode/settings.json
:{ "less.compile": { "main": ["main-one.less", "main-two.less"] } }
Per file: by specifying the
main
setting key more than once:// main: "main-one.less", main: "main-two.less"
When there is more than one
main
setting, they are guaranteed to be output in the order listed (from left to right). For the example shown above, the output frommain-one.less
will be saved to disk beforemain-two.less
is processed (assuming they are both configured to output). This can be used to control dependency chains.
Can I specify paths relative to the workspace, instead of relative to the less file?
Yes, the variable
${workspaceFolder}
can be used within themain
orout
parameters:
.vscode/settings.json
:{ "less.compile": { "main": ["${workspaceFolder}/css/main.less"] } }
How do I generate sourcemap (*.css.map
) files?
.vscode/settings.json
:{ "less.compile": { "sourceMap": true } }
How do I resolve the error "Inline JavaScript is not enabled. Is it set in your options?"
?
Inline JavaScript is a feature of LESS that used to be enabled by default. It was disabled by default in v3.0.0 of LESS for security reasons. You can use the
javascriptEnabled
setting to override this behaviour by setting the value totrue
.If you receive this error unintentionally, there are most likely one or more backticks (``) in your .less file.
Can I add custom pre-processing to my less files before they are converted to CSS?
Yes! This extension is itself extensible.
It provides a very basic API that can be used by another VS Code extension to > add any custom preprocessing that is required. The input to the preprocessor is the
.less
file contents (as astring
). The expected output is also astring
of less syntax.Example:
// Within your own VS Code extension... import { extensions } from 'vscode'; // API type definitions. type EasyLessAPI = { registerPreprocessor: (processor: PreprocessorFn): void }; type PreprocessorFn = (less: string, ctx: Map<string, any>) => Promise<string> | string; // Overly-simplified preprocessor to convert "em" to "rem". const emToRem: PreprocessorFn = async (less: string) => { return context.replace(/(?<=[\d\s])em\b/g, 'rem'); }; // Activation function for your extension. export function activate(context: vscode.ExtensionContext) { // Get reference to EasyLESS extension. const extension = extensions.getExtension('mrcrowl.easy-less'); if (!api) { console.error('EasyLESS is not installed or available.'); } // Register emToRem as a less preprocessor. const api: EasyLessAPI = extension.exports; api.exports.registerPreprocessor(emToRem); } }
Preprocessor functions can also return either a plain
string
or aPromise<string>
depending on if any async processing is required.Extension Activation
In order for your custom extension to activate, it is important that the following activation event is declared the in extension manifest (the
package.json
file for the extension):"activationEvents": [ "onLanguage:less" ],
This ensures that your extension is appropriately activated by VS Code.
References
Learn more about VS Code extensions and how they can be made extensibile by other extensions:
- Overview of VS Code Extensions
- API reference — Extensibility
extensions.getExtension()
apiExtension<T>
type
🎩 HT to northwang-lucky for introducing this extensibility feature.