From d0db4f9839c4921440c9a0fdc00fd00bc5a6fbb8 Mon Sep 17 00:00:00 2001 From: Alexey Lavinsky Date: Thu, 7 May 2020 15:33:48 +0300 Subject: [PATCH] fix: respect third-party plugins for `Less` (#353) --- src/utils.js | 2 +- test/__snapshots__/loader.test.js.snap | 20 ++++++++++++++ test/fixtures/file-load-replacement.less | 3 +++ test/fixtures/file-load.less | 3 +++ .../fixtures/folder/customFileLoaderPlugin.js | 26 +++++++++++++++++++ test/helpers/getCodeFromLess.js | 11 +++++--- test/loader.test.js | 22 ++++++++++++++++ 7 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/file-load-replacement.less create mode 100644 test/fixtures/file-load.less create mode 100644 test/fixtures/folder/customFileLoaderPlugin.js diff --git a/src/utils.js b/src/utils.js index 1c1f6c1d..fb7d25f4 100644 --- a/src/utils.js +++ b/src/utils.js @@ -156,7 +156,7 @@ function getLessOptions(loaderContext, loaderOptions) { ...options, }; - lessOptions.plugins.push(createWebpackLessPlugin(loaderContext)); + lessOptions.plugins.unshift(createWebpackLessPlugin(loaderContext)); const useSourceMap = typeof loaderOptions.sourceMap === 'boolean' diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index bf41bf2b..ef36b9b6 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -323,6 +323,26 @@ exports[`loader should transform urls: errors 1`] = `Array []`; exports[`loader should transform urls: warnings 1`] = `Array []`; +exports[`loader should work third-party plugins as fileLoader: css 1`] = ` +".file-loader { + background: coral; +} +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9fBBc9.ttf) format('truetype'); +} +.modules-dir-scope-module { + color: hotpink; +} +" +`; + +exports[`loader should work third-party plugins as fileLoader: errors 1`] = `Array []`; + +exports[`loader should work third-party plugins as fileLoader: warnings 1`] = `Array []`; + exports[`loader should work: css 1`] = ` ".box { color: #fe33ac; diff --git a/test/fixtures/file-load-replacement.less b/test/fixtures/file-load-replacement.less new file mode 100644 index 00000000..074e9a0f --- /dev/null +++ b/test/fixtures/file-load-replacement.less @@ -0,0 +1,3 @@ +.file-loader { + background: coral; +} diff --git a/test/fixtures/file-load.less b/test/fixtures/file-load.less new file mode 100644 index 00000000..928fd8d0 --- /dev/null +++ b/test/fixtures/file-load.less @@ -0,0 +1,3 @@ +@import "forFileLoaderPluginResolve.less"; +@import (once) url("https://fonts.googleapis.com/css?family=Roboto:500"); +@import "~@scope/module"; diff --git a/test/fixtures/folder/customFileLoaderPlugin.js b/test/fixtures/folder/customFileLoaderPlugin.js new file mode 100644 index 00000000..ce318248 --- /dev/null +++ b/test/fixtures/folder/customFileLoaderPlugin.js @@ -0,0 +1,26 @@ +import path from "path"; +import less from "less"; + +class Plugin extends less.FileManager { + supports(filename) { + if (filename === 'forFileLoaderPluginResolve.less') { + return true; + } + + return false; + } + + loadFile(filename, ...args) { + const result = path.resolve(__dirname, '../', 'file-load-replacement.less'); + + return super.loadFile(result, ...args); + }; +} + +class CustomFileLoaderPlugin { + install(less, pluginManager) { + pluginManager.addFileManager(new Plugin()); + } +} + +module.exports = CustomFileLoaderPlugin; diff --git a/test/helpers/getCodeFromLess.js b/test/helpers/getCodeFromLess.js index 971be21c..36656584 100644 --- a/test/helpers/getCodeFromLess.js +++ b/test/helpers/getCodeFromLess.js @@ -96,17 +96,20 @@ class CustomImportPlugin { async function getCodeFromLess(testId, options = {}) { const pathToFile = path.resolve(__dirname, '..', 'fixtures', testId); const defaultOptions = { - plugins: [new CustomImportPlugin()], + plugins: [], relativeUrls: true, filename: pathToFile, }; const lessOptions = options.lessOptions || {}; const data = await fs.promises.readFile(pathToFile); - - const result = await less.render(data.toString(), { + const mergedOptions = { ...defaultOptions, ...lessOptions, - }); + }; + + mergedOptions.plugins.unshift(new CustomImportPlugin()); + + const result = await less.render(data.toString(), mergedOptions); return result; } diff --git a/test/loader.test.js b/test/loader.test.js index 97bc7c17..340038f8 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -1,6 +1,7 @@ import path from 'path'; import CustomImportPlugin from './fixtures/folder/customImportPlugin'; +import CustomFileLoaderPlugin from './fixtures/folder/customFileLoaderPlugin'; import { compile, @@ -99,6 +100,27 @@ describe('loader', () => { expect(getErrors(stats)).toMatchSnapshot('errors'); }); + it('should work third-party plugins as fileLoader', async () => { + const testId = './file-load.less'; + const compiler = getCompiler(testId, { + lessOptions: { + plugins: [new CustomFileLoaderPlugin()], + }, + }); + const stats = await compile(compiler); + const codeFromBundle = getCodeFromBundle(stats, compiler); + const codeFromLess = await getCodeFromLess(testId, { + lessOptions: { + plugins: [new CustomFileLoaderPlugin()], + }, + }); + + expect(codeFromBundle.css).toBe(codeFromLess.css); + expect(codeFromBundle.css).toMatchSnapshot('css'); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + }); + it('should not alter the original options object', async () => { const options = { lessOptions: { plugins: [] } }; const copiedOptions = { ...options };