UNPKG

15.3 kBMarkdownView Raw
1<div align="center">
2 <a href="https://github.com/webpack/webpack">
3 <img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
4 </a>
5</div>
6
7[![npm][npm]][npm-url]
8[![node][node]][node-url]
9[![deps][deps]][deps-url]
10[![tests][tests]][tests-url]
11[![cover][cover]][cover-url]
12[![chat][chat]][chat-url]
13[![size][size]][size-url]
14
15# less-loader
16
17A Less loader for webpack. Compiles Less to CSS.
18
19## Getting Started
20
21To begin, you'll need to install `less-loader`:
22
23```console
24$ npm install less-loader --save-dev
25```
26
27Then add the loader to your `webpack` config. For example:
28
29**webpack.config.js**
30
31```js
32module.exports = {
33 module: {
34 rules: [
35 {
36 test: /\.less$/,
37 loader: 'less-loader', // compiles Less to CSS
38 },
39 ],
40 },
41};
42```
43
44And run `webpack` via your preferred method.
45
46## Options
47
48| Name | Type | Default | Description |
49| :-------------------------------------: | :------------------: | :----------------------: | :----------------------------------------------- |
50| **[`lessOptions`](#lessoptions)** | `{Object\|Function}` | `{ relativeUrls: true }` | Options for Less. |
51| **[`prependData`](#prependdata)** | `{String\|Function}` | `undefined` | Prepends Less code before the actual entry file. |
52| **[`appendData`](#appenddata)** | `{String\|Function}` | `undefined` | Prepends Less code after the actual entry file. |
53| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. |
54| **[`implementation`](#implementation)** | `{Object}` | `less` | Setup Less implementation to use. |
55
56### `lessOptions`
57
58Type: `Object|Function`
59Default: `{ relativeUrls: true }`
60
61You can pass any Less specific options to the `less-loader` through the `lessOptions` property in the [loader options](https://webpack.js.org/configuration/module/#rule-options-rule-query). See the [Less documentation](http://lesscss.org/usage/#command-line-usage-options) for all available options in dash-case. Since we're passing these options to Less programmatically, you need to pass them in camelCase here:
62
63#### `Object`
64
65Use an object to pass options through to Less.
66
67**webpack.config.js**
68
69```js
70module.exports = {
71 module: {
72 rules: [
73 {
74 test: /\.less$/,
75 use: [
76 {
77 loader: 'style-loader',
78 },
79 {
80 loader: 'css-loader',
81 },
82 {
83 loader: 'less-loader',
84 options: {
85 lessOptions: {
86 strictMath: true,
87 },
88 },
89 },
90 ],
91 },
92 ],
93 },
94};
95```
96
97#### `Function`
98
99Allows setting the options passed through to Less based off of the loader context.
100
101```js
102module.exports = {
103 module: {
104 rules: [
105 {
106 test: /\.less$/,
107 use: [
108 'style-loader',
109 'css-loader',
110 {
111 loader: 'less-loader',
112 options: {
113 lessOptions: (loaderContext) => {
114 // More information about available properties https://webpack.js.org/api/loaders/
115 const { resourcePath, rootContext } = loaderContext;
116 const relativePath = path.relative(rootContext, resourcePath);
117
118 if (relativePath === 'styles/foo.less') {
119 return {
120 paths: ['absolute/path/c', 'absolute/path/d'],
121 };
122 }
123
124 return {
125 paths: ['absolute/path/a', 'absolute/path/b'],
126 };
127 },
128 },
129 },
130 ],
131 },
132 ],
133 },
134};
135```
136
137### `prependData`
138
139Type: `String|Function`
140Default: `undefined`
141
142Prepends `Less` code before the actual entry file.
143
144This is especially useful when some of your Less variables depend on the environment:
145
146> ℹ Since you're injecting code, this will break the source mappings in your entry file. Often there's a simpler solution than this, like multiple Less entry files.
147
148#### `String`
149
150```js
151module.exports = {
152 module: {
153 rules: [
154 {
155 test: /\.less$/,
156 use: [
157 'style-loader',
158 'css-loader',
159 {
160 loader: 'less-loader',
161 options: {
162 prependData: `@env: ${process.env.NODE_ENV};`,
163 },
164 },
165 ],
166 },
167 ],
168 },
169};
170```
171
172#### `Function`
173
174```js
175module.exports = {
176 module: {
177 rules: [
178 {
179 test: /\.less$/,
180 use: [
181 'style-loader',
182 'css-loader',
183 {
184 loader: 'less-loader',
185 options: {
186 prependData: (loaderContext) => {
187 // More information about available properties https://webpack.js.org/api/loaders/
188 const { resourcePath, rootContext } = loaderContext;
189 const relativePath = path.relative(rootContext, resourcePath);
190
191 if (relativePath === 'styles/foo.less') {
192 return '@value: 100px;';
193 }
194
195 return '@value: 200px;';
196 },
197 },
198 },
199 ],
200 },
201 ],
202 },
203};
204```
205
206### `appendData`
207
208Type: `String|Function`
209Default: `undefined`
210
211AppendData `Less` code after the actual entry file.
212
213This can be useful when you need to rewrite some of your Less variables.:
214
215> ℹ Since you're injecting code, this will break the source mappings in your entry file. Often there's a simpler solution than this, like multiple Less entry files.
216
217#### `String`
218
219```js
220module.exports = {
221 module: {
222 rules: [
223 {
224 test: /\.less$/,
225 use: [
226 'style-loader',
227 'css-loader',
228 {
229 loader: 'less-loader',
230 options: {
231 appendData: `@env: ${process.env.NODE_ENV};`,
232 },
233 },
234 ],
235 },
236 ],
237 },
238};
239```
240
241#### `Function`
242
243```js
244module.exports = {
245 module: {
246 rules: [
247 {
248 test: /\.less$/,
249 use: [
250 'style-loader',
251 'css-loader',
252 {
253 loader: 'less-loader',
254 options: {
255 appendData: (loaderContext) => {
256 // More information about available properties https://webpack.js.org/api/loaders/
257 const { resourcePath, rootContext } = loaderContext;
258 const relativePath = path.relative(rootContext, resourcePath);
259
260 if (relativePath === 'styles/foo.less') {
261 return '@value: 100px;';
262 }
263
264 return '@value: 200px;';
265 },
266 },
267 },
268 ],
269 },
270 ],
271 },
272};
273```
274
275### `sourceMap`
276
277Type: `Boolean`
278Default: depends on the `compiler.devtool` value
279
280By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option. All values enable source map generation except `eval` and `false` value.
281
282**webpack.config.js**
283
284```js
285module.exports = {
286 module: {
287 rules: [
288 {
289 test: /\.less$/i,
290 use: [
291 'style-loader',
292 {
293 loader: 'css-loader',
294 options: {
295 sourceMap: true,
296 },
297 },
298 {
299 loader: 'less-loader',
300 options: {
301 sourceMap: true,
302 },
303 },
304 ],
305 },
306 ],
307 },
308};
309```
310
311### `implementation`
312
313Type: `Object`
314Default: `less`
315
316> ⚠ less-loader compatible with Less version 3 only
317
318The special `implementation` option determines which implementation of Less to use.
319The `implementation` options either accepts `less` as a module.
320This is useful if you want to use Less with a smaller version. Do not forget that then you must install your own version of Less.
321
322For example, to use custom Less implementation, you'd pass:
323
324```js
325module.exports = {
326 module: {
327 rules: [
328 {
329 test: /\.less$/,
330 use: [
331 'style-loader',
332 'css-loader',
333 {
334 loader: 'less-loader',
335 options: {
336 implementation: require('less'),
337 },
338 },
339 ],
340 },
341 ],
342 },
343};
344```
345
346## Examples
347
348### Normal usage
349
350Chain the `less-loader` with the [`css-loader`](https://github.com/webpack-contrib/css-loader) and the [`style-loader`](https://github.com/webpack-contrib/style-loader) to immediately apply all styles to the DOM.
351
352**webpack.config.js**
353
354```js
355module.exports = {
356 module: {
357 rules: [
358 {
359 test: /\.less$/,
360 use: [
361 {
362 loader: 'style-loader', // creates style nodes from JS strings
363 },
364 {
365 loader: 'css-loader', // translates CSS into CommonJS
366 },
367 {
368 loader: 'less-loader', // compiles Less to CSS
369 },
370 ],
371 },
372 ],
373 },
374};
375```
376
377Unfortunately, Less doesn't map all options 1-by-1 to camelCase. When in doubt, [check their executable](https://github.com/less/less.js/blob/3.x/bin/lessc) and search for the dash-case option.
378
379### Source maps
380
381To enable sourcemaps for CSS, you'll need to pass the `sourceMap` property in the loader's options. If this is not passed, the loader will respect the setting for webpack source maps, set in `devtool`.
382
383**webpack.config.js**
384
385```javascript
386module.exports = {
387 devtool: 'source-map', // any "source-map"-like devtool is possible
388 module: {
389 rules: [
390 {
391 test: /\.less$/,
392 use: [
393 'style-loader',
394 {
395 loader: 'css-loader',
396 options: {
397 sourceMap: true,
398 },
399 },
400 {
401 loader: 'less-loader',
402 options: {
403 sourceMap: true,
404 },
405 },
406 ],
407 },
408 ],
409 },
410};
411```
412
413If you want to edit the original Less files inside Chrome, [there's a good blog post](https://medium.com/@toolmantim/getting-started-with-css-sourcemaps-and-in-browser-sass-editing-b4daab987fb0). The blog post is about Sass but it also works for Less.
414
415### In production
416
417Usually, it's recommended to extract the style sheets into a dedicated file in production using the [MiniCssExtractPlugin](https://github.com/webpack-contrib/mini-css-extract-plugin). This way your styles are not dependent on JavaScript.
418
419### Imports
420
421Starting with `less-loader` 4, you can now choose between Less' builtin resolver and webpack's resolver. By default, webpack's resolver is used.
422
423#### webpack resolver
424
425webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/configuration/resolve/). The `less-loader` applies a Less plugin that passes all queries to the webpack resolver. Thus you can import your Less modules from `node_modules`. Just prepend them with a `~` which tells webpack to look up the [`modules`](https://webpack.js.org/configuration/resolve/#resolve-modules).
426
427```css
428@import '~bootstrap/less/bootstrap';
429```
430
431It's important to only prepend it with `~`, because `~/` resolves to the home-directory. webpack needs to distinguish between `bootstrap` and `~bootstrap`, because CSS and Less files have no special syntax for importing relative files. Writing `@import "file"` is the same as `@import "./file";`
432
433##### Non-Less imports
434
435Using webpack's resolver, you can import any file type. You just need a loader that exports valid Less code. Often, you will also want to set the `issuer` condition to ensure that this rule is only applied on imports originating from Less files:
436
437```js
438// webpack.config.js
439module.exports = {
440 module: {
441 rules: [
442 {
443 test: /\.js$/,
444 issuer: /\.less$/,
445 use: [
446 {
447 loader: 'js-to-less-loader',
448 },
449 ],
450 },
451 ],
452 },
453};
454```
455
456#### Less resolver
457
458If you specify the `paths` option, modules will be searched in the given `paths`. This is Less' default behavior. `paths` should be an array with absolute paths:
459
460**webpack.config.js**
461
462```js
463module.exports = {
464 module: {
465 rules: [
466 {
467 test: /\.less$/,
468 use: [
469 {
470 loader: 'style-loader',
471 },
472 {
473 loader: 'css-loader',
474 },
475 {
476 loader: 'less-loader',
477 options: {
478 lessOptions: {
479 paths: [path.resolve(__dirname, 'node_modules')],
480 },
481 },
482 },
483 ],
484 },
485 ],
486 },
487};
488```
489
490### Plugins
491
492In order to use [plugins](http://lesscss.org/usage/#plugins), simply set the
493`plugins` option like this:
494
495```js
496// webpack.config.js
497const CleanCSSPlugin = require('less-plugin-clean-css');
498
499module.exports = {
500 ...
501 {
502 loader: 'less-loader',
503 options: {
504 lessOptions: {
505 plugins: [
506 new CleanCSSPlugin({ advanced: true }),
507 ],
508 },
509 },
510 },
511 ...
512};
513```
514
515### Extracting style sheets
516
517Bundling CSS with webpack has some nice advantages like referencing images and fonts with hashed urls or [hot module replacement](https://webpack.js.org/concepts/hot-module-replacement/) in development. In production, on the other hand, it's not a good idea to apply your style sheets depending on JS execution. Rendering may be delayed or even a [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) might be visible. Thus it's often still better to have them as separate files in your final production build.
518
519There are two possibilities to extract a style sheet from the bundle:
520
521- [`extract-loader`](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
522- [MiniCssExtractPlugin](https://github.com/webpack-contrib/mini-css-extract-plugin) (more complex, but works in all use-cases)
523
524### CSS modules gotcha
525
526There is a known problem with Less and [CSS modules](https://github.com/css-modules/css-modules) regarding relative file paths in `url(...)` statements. [See this issue for an explanation](https://github.com/webpack-contrib/less-loader/issues/109#issuecomment-253797335).
527
528## Contributing
529
530Please take a moment to read our contributing guidelines if you haven't yet done so.
531
532[CONTRIBUTING](./.github/CONTRIBUTING.md)
533
534## License
535
536[MIT](./LICENSE)
537
538[npm]: https://img.shields.io/npm/v/less-loader.svg
539[npm-url]: https://npmjs.com/package/less-loader
540[node]: https://img.shields.io/node/v/less-loader.svg
541[node-url]: https://nodejs.org
542[deps]: https://david-dm.org/webpack-contrib/less-loader.svg
543[deps-url]: https://david-dm.org/webpack-contrib/less-loader
544[tests]: https://github.com/webpack-contrib/less-loader/workflows/less-loader/badge.svg
545[tests-url]: https://github.com/webpack-contrib/less-loader/actions
546[cover]: https://codecov.io/gh/webpack-contrib/less-loader/branch/master/graph/badge.svg
547[cover-url]: https://codecov.io/gh/webpack-contrib/less-loader
548[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
549[chat-url]: https://gitter.im/webpack/webpack
550[size]: https://packagephobia.now.sh/badge?p=less-loader
551[size-url]: https://packagephobia.now.sh/result?p=less-loader