Skip to content

Commit d0db4f9

Browse files
fix: respect third-party plugins for Less (#353)
1 parent 73740a8 commit d0db4f9

File tree

7 files changed

+82
-5
lines changed

7 files changed

+82
-5
lines changed

src/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ function getLessOptions(loaderContext, loaderOptions) {
156156
...options,
157157
};
158158

159-
lessOptions.plugins.push(createWebpackLessPlugin(loaderContext));
159+
lessOptions.plugins.unshift(createWebpackLessPlugin(loaderContext));
160160

161161
const useSourceMap =
162162
typeof loaderOptions.sourceMap === 'boolean'

test/__snapshots__/loader.test.js.snap

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,26 @@ exports[`loader should transform urls: errors 1`] = `Array []`;
323323
324324
exports[`loader should transform urls: warnings 1`] = `Array []`;
325325
326+
exports[`loader should work third-party plugins as fileLoader: css 1`] = `
327+
".file-loader {
328+
background: coral;
329+
}
330+
@font-face {
331+
font-family: 'Roboto';
332+
font-style: normal;
333+
font-weight: 500;
334+
src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9fBBc9.ttf) format('truetype');
335+
}
336+
.modules-dir-scope-module {
337+
color: hotpink;
338+
}
339+
"
340+
`;
341+
342+
exports[`loader should work third-party plugins as fileLoader: errors 1`] = `Array []`;
343+
344+
exports[`loader should work third-party plugins as fileLoader: warnings 1`] = `Array []`;
345+
326346
exports[`loader should work: css 1`] = `
327347
".box {
328348
color: #fe33ac;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.file-loader {
2+
background: coral;
3+
}

test/fixtures/file-load.less

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@import "forFileLoaderPluginResolve.less";
2+
@import (once) url("https://fonts.googleapis.com/css?family=Roboto:500");
3+
@import "~@scope/module";
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import path from "path";
2+
import less from "less";
3+
4+
class Plugin extends less.FileManager {
5+
supports(filename) {
6+
if (filename === 'forFileLoaderPluginResolve.less') {
7+
return true;
8+
}
9+
10+
return false;
11+
}
12+
13+
loadFile(filename, ...args) {
14+
const result = path.resolve(__dirname, '../', 'file-load-replacement.less');
15+
16+
return super.loadFile(result, ...args);
17+
};
18+
}
19+
20+
class CustomFileLoaderPlugin {
21+
install(less, pluginManager) {
22+
pluginManager.addFileManager(new Plugin());
23+
}
24+
}
25+
26+
module.exports = CustomFileLoaderPlugin;

test/helpers/getCodeFromLess.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,20 @@ class CustomImportPlugin {
9696
async function getCodeFromLess(testId, options = {}) {
9797
const pathToFile = path.resolve(__dirname, '..', 'fixtures', testId);
9898
const defaultOptions = {
99-
plugins: [new CustomImportPlugin()],
99+
plugins: [],
100100
relativeUrls: true,
101101
filename: pathToFile,
102102
};
103103
const lessOptions = options.lessOptions || {};
104104
const data = await fs.promises.readFile(pathToFile);
105-
106-
const result = await less.render(data.toString(), {
105+
const mergedOptions = {
107106
...defaultOptions,
108107
...lessOptions,
109-
});
108+
};
109+
110+
mergedOptions.plugins.unshift(new CustomImportPlugin());
111+
112+
const result = await less.render(data.toString(), mergedOptions);
110113

111114
return result;
112115
}

test/loader.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from 'path';
22

33
import CustomImportPlugin from './fixtures/folder/customImportPlugin';
4+
import CustomFileLoaderPlugin from './fixtures/folder/customFileLoaderPlugin';
45

56
import {
67
compile,
@@ -99,6 +100,27 @@ describe('loader', () => {
99100
expect(getErrors(stats)).toMatchSnapshot('errors');
100101
});
101102

103+
it('should work third-party plugins as fileLoader', async () => {
104+
const testId = './file-load.less';
105+
const compiler = getCompiler(testId, {
106+
lessOptions: {
107+
plugins: [new CustomFileLoaderPlugin()],
108+
},
109+
});
110+
const stats = await compile(compiler);
111+
const codeFromBundle = getCodeFromBundle(stats, compiler);
112+
const codeFromLess = await getCodeFromLess(testId, {
113+
lessOptions: {
114+
plugins: [new CustomFileLoaderPlugin()],
115+
},
116+
});
117+
118+
expect(codeFromBundle.css).toBe(codeFromLess.css);
119+
expect(codeFromBundle.css).toMatchSnapshot('css');
120+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
121+
expect(getErrors(stats)).toMatchSnapshot('errors');
122+
});
123+
102124
it('should not alter the original options object', async () => {
103125
const options = { lessOptions: { plugins: [] } };
104126
const copiedOptions = { ...options };

0 commit comments

Comments
 (0)