Skip to content

Commit db6fbdd

Browse files
author
Ryan Clark
committed
feat: allow data to be prepended via options.prependData
1 parent a6be94a commit db6fbdd

File tree

6 files changed

+116
-3
lines changed

6 files changed

+116
-3
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,75 @@ module.exports = {
8484
};
8585
```
8686

87+
### `prependData`
88+
89+
Type: `String|Function`
90+
Default: `undefined`
91+
92+
Prepends `Less` code before the actual entry file.
93+
94+
This is especially useful when some of your Less variables depend on the environment:
95+
96+
> ℹ 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.
97+
98+
#### `String`
99+
100+
```js
101+
module.exports = {
102+
module: {
103+
rules: [
104+
{
105+
test: /\.less$/,
106+
use: [
107+
'style-loader',
108+
'css-loader',
109+
{
110+
loader: 'less-loader',
111+
options: {
112+
prependData: `@env: ${process.env.NODE_ENV};`,
113+
},
114+
},
115+
],
116+
},
117+
],
118+
},
119+
};
120+
```
121+
122+
#### `Function`
123+
124+
```js
125+
module.exports = {
126+
module: {
127+
rules: [
128+
{
129+
test: /\.less$/,
130+
use: [
131+
'style-loader',
132+
'css-loader',
133+
{
134+
loader: 'less-loader',
135+
options: {
136+
prependData: (loaderContext) => {
137+
// More information about available properties https://webpack.js.org/api/loaders/
138+
const { resourcePath, rootContext } = loaderContext;
139+
const relativePath = path.relative(rootContext, resourcePath);
140+
141+
if (relativePath === 'styles/foo.scss') {
142+
return '@value: 100px;';
143+
}
144+
145+
return '@value: 200px;';
146+
},
147+
},
148+
},
149+
],
150+
},
151+
],
152+
},
153+
};
154+
```
155+
87156
### `sourceMap`
88157

89158
Type: `Boolean`

src/getLessOptions.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os from 'os';
2+
13
import clone from 'clone';
24

35
import createWebpackLessPlugin from './createWebpackLessPlugin';
@@ -7,9 +9,10 @@ import createWebpackLessPlugin from './createWebpackLessPlugin';
79
*
810
* @param {object} loaderContext
911
* @param {object} loaderOptions
12+
* @param {string} content
1013
* @returns {Object}
1114
*/
12-
function getLessOptions(loaderContext, loaderOptions) {
15+
function getLessOptions(loaderContext, loaderOptions, content) {
1316
const options = clone(
1417
loaderOptions.lessOptions
1518
? typeof loaderOptions.lessOptions === 'function'
@@ -18,12 +21,19 @@ function getLessOptions(loaderContext, loaderOptions) {
1821
: {}
1922
);
2023

24+
const data = loaderOptions.prependData
25+
? typeof loaderOptions.prependData === 'function'
26+
? loaderOptions.prependData(loaderContext) + os.EOL + content
27+
: loaderOptions.prependData + os.EOL + content
28+
: content;
29+
2130
const lessOptions = {
2231
plugins: [],
2332
relativeUrls: true,
2433
// We need to set the filename because otherwise our WebpackFileManager will receive an undefined path for the entry
2534
filename: loaderContext.resourcePath,
2635
...options,
36+
data,
2737
};
2838

2939
if (typeof lessOptions.paths === 'undefined') {

src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ function lessLoader(source) {
2020
});
2121

2222
const callback = this.async();
23-
const lessOptions = getLessOptions(this, options);
23+
const lessOptions = getLessOptions(this, options, source);
2424

25-
processResult(this, render(source, lessOptions), callback);
25+
processResult(this, render(lessOptions.data, lessOptions), callback);
2626
}
2727

2828
export default lessLoader;

src/options.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@
1313
}
1414
]
1515
},
16+
"prependData": {
17+
"description": "Prepends `Less` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata).",
18+
"anyOf": [
19+
{
20+
"type": "string"
21+
},
22+
{
23+
"instanceof": "Function"
24+
}
25+
]
26+
},
1627
"sourceMap": {
1728
"description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/less-loader#sourcemap).",
1829
"type": "boolean"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.background {
2+
color: @background;
3+
}

test/index.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ test("should resolve all imports from the given paths using Less' resolver", asy
128128
});
129129
});
130130

131+
test('should prepend data', async () => {
132+
const loaderOptions = {
133+
prependData() {
134+
return `@background: red;`;
135+
},
136+
};
137+
138+
let inspect;
139+
140+
const rules = moduleRules.basic(loaderOptions, {}, (i) => {
141+
inspect = i;
142+
});
143+
144+
await compile('prepend-data', rules).catch((e) => e);
145+
146+
const [css] = inspect.arguments;
147+
148+
expect(css).toEqual('.background {\n color: red;\n}\n');
149+
});
150+
131151
test('should allow a function to be passed through for `lessOptions`', async () => {
132152
await compileAndCompare('import-paths', {
133153
lessLoaderOptions: {

0 commit comments

Comments
 (0)