Skip to content

Commit 9df8755

Browse files
author
Ryan Clark
authoredMar 16, 2020
feat: allow data to be prepended via options.prependData (#327)
1 parent ce03da9 commit 9df8755

File tree

6 files changed

+117
-4
lines changed

6 files changed

+117
-4
lines changed
 

‎README.md

+70-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ module.exports = {
109109
const { resourcePath, rootContext } = loaderContext;
110110
const relativePath = path.relative(rootContext, resourcePath);
111111

112-
if (relativePath === 'styles/foo.scss') {
112+
if (relativePath === 'styles/foo.less') {
113113
return {
114114
paths: ['absolute/path/c', 'absolute/path/d'],
115115
};
@@ -128,6 +128,75 @@ module.exports = {
128128
};
129129
```
130130

131+
### `prependData`
132+
133+
Type: `String|Function`
134+
Default: `undefined`
135+
136+
Prepends `Less` code before the actual entry file.
137+
138+
This is especially useful when some of your Less variables depend on the environment:
139+
140+
> ℹ 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.
141+
142+
#### `String`
143+
144+
```js
145+
module.exports = {
146+
module: {
147+
rules: [
148+
{
149+
test: /\.less$/,
150+
use: [
151+
'style-loader',
152+
'css-loader',
153+
{
154+
loader: 'less-loader',
155+
options: {
156+
prependData: `@env: ${process.env.NODE_ENV};`,
157+
},
158+
},
159+
],
160+
},
161+
],
162+
},
163+
};
164+
```
165+
166+
#### `Function`
167+
168+
```js
169+
module.exports = {
170+
module: {
171+
rules: [
172+
{
173+
test: /\.less$/,
174+
use: [
175+
'style-loader',
176+
'css-loader',
177+
{
178+
loader: 'less-loader',
179+
options: {
180+
prependData: (loaderContext) => {
181+
// More information about available properties https://webpack.js.org/api/loaders/
182+
const { resourcePath, rootContext } = loaderContext;
183+
const relativePath = path.relative(rootContext, resourcePath);
184+
185+
if (relativePath === 'styles/foo.less') {
186+
return '@value: 100px;';
187+
}
188+
189+
return '@value: 200px;';
190+
},
191+
},
192+
},
193+
],
194+
},
195+
],
196+
},
197+
};
198+
```
199+
131200
### `sourceMap`
132201

133202
Type: `Boolean`

‎src/getLessOptions.js

+11-1
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

+2-2
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

+11
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"

‎test/fixtures/less/prepend-data.less

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.background {
2+
color: @background;
3+
}

‎test/index.test.js

+20
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)
Please sign in to comment.