From da0be65399407c10461af283abf1f0dc0e696978 Mon Sep 17 00:00:00 2001 From: paniuncle <1173440278@qq.com> Date: Thu, 24 Apr 2025 19:58:57 +0800 Subject: [PATCH 1/2] fix: add onlyWebpackImporter option --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ src/utils.js | 3 ++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a90a2b..1021f9d 100644 --- a/README.md +++ b/README.md @@ -346,6 +346,45 @@ module.exports = { }; ``` +### `onlyWebpackImporter` + +Type: + +```ts +type onlyWebpackImporter = boolean; +``` + +Default: `true` + +Enables/Disables the only use `webpack` importer. + +This can improve performance in some cases. Use it with caution because aliases and `@import` from [`node_modules`](https://webpack.js.org/configuration/resolve/#resolvemodules) will not work. + +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.less$/i, + use: [ + "style-loader", + "css-loader", + { + loader: "less-loader", + options: { + webpackImporter: true, + onlyWebpackImporter: true, + }, + }, + ], + }, + ], + }, +}; +``` + ### `implementation` Type: diff --git a/src/utils.js b/src/utils.js index e4a0c00..17ee302 100644 --- a/src/utils.js +++ b/src/utils.js @@ -30,6 +30,7 @@ const MODULE_REQUEST_REGEX = /^[^?]*~/; * @returns {LessPlugin} */ function createWebpackLessPlugin(loaderContext, implementation) { + const lessOptions = loaderContext.getOptions(); const resolve = loaderContext.getResolve({ dependencyType: "less", conditionNames: ["less", "style", "..."], @@ -105,7 +106,7 @@ function createWebpackLessPlugin(loaderContext, implementation) { let result; try { - if (IS_SPECIAL_MODULE_IMPORT.test(filename)) { + if (IS_SPECIAL_MODULE_IMPORT.test(filename) || lessOptions.onlyWebpackImporter) { const error = new Error(); error.type = "Next"; From 9a2edd7a4e60f68a695fdbf252082be1f077e29b Mon Sep 17 00:00:00 2001 From: paniuncle <1173440278@qq.com> Date: Thu, 24 Apr 2025 23:06:03 +0800 Subject: [PATCH 2/2] feat: use the webpackImporter var and add unit test --- README.md | 41 +------------------ src/options.json | 10 ++++- src/utils.js | 8 +++- .../validate-options.test.js.snap | 8 +++- .../webpackImporter-options.test.js.snap | 20 +++++++++ test/validate-options.test.js | 2 +- test/webpackImporter-options.test.js | 15 +++++++ 7 files changed, 58 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 1021f9d..b1dfa43 100644 --- a/README.md +++ b/README.md @@ -313,7 +313,7 @@ module.exports = { Type: ```ts -type webpackImporter = boolean; +type webpackImporter = boolean | "only"; ``` Default: `true` @@ -346,45 +346,6 @@ module.exports = { }; ``` -### `onlyWebpackImporter` - -Type: - -```ts -type onlyWebpackImporter = boolean; -``` - -Default: `true` - -Enables/Disables the only use `webpack` importer. - -This can improve performance in some cases. Use it with caution because aliases and `@import` from [`node_modules`](https://webpack.js.org/configuration/resolve/#resolvemodules) will not work. - -**webpack.config.js** - -```js -module.exports = { - module: { - rules: [ - { - test: /\.less$/i, - use: [ - "style-loader", - "css-loader", - { - loader: "less-loader", - options: { - webpackImporter: true, - onlyWebpackImporter: true, - }, - }, - ], - }, - ], - }, -}; -``` - ### `implementation` Type: diff --git a/src/options.json b/src/options.json index 36f18a9..5cc74db 100644 --- a/src/options.json +++ b/src/options.json @@ -35,7 +35,15 @@ "webpackImporter": { "description": "Enables/Disables default `webpack` importer.", "link": "https://github.com/webpack-contrib/less-loader#webpackimporter", - "type": "boolean" + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string", + "enum": ["only"] + } + ] }, "implementation": { "description": "The implementation of the `Less` to be used.", diff --git a/src/utils.js b/src/utils.js index 17ee302..2b65b91 100644 --- a/src/utils.js +++ b/src/utils.js @@ -106,7 +106,10 @@ function createWebpackLessPlugin(loaderContext, implementation) { let result; try { - if (IS_SPECIAL_MODULE_IMPORT.test(filename) || lessOptions.onlyWebpackImporter) { + if ( + IS_SPECIAL_MODULE_IMPORT.test(filename) || + lessOptions.webpackImporter === "only" + ) { const error = new Error(); error.type = "Next"; @@ -178,7 +181,8 @@ function getLessOptions(loaderContext, loaderOptions, implementation) { const plugins = lessOptions.plugins.slice(); const shouldUseWebpackImporter = - typeof loaderOptions.webpackImporter === "boolean" + typeof loaderOptions.webpackImporter === "boolean" || + loaderOptions.webpackImporter === "only" ? loaderOptions.webpackImporter : true; diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index 57ac7c0..621d817 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -238,7 +238,11 @@ exports[`validate options should throw an error on the "unknown" option with "tr exports[`validate options should throw an error on the "webpackImporter" option with "string" value 1`] = ` "Invalid options object. Less Loader has been initialized using an options object that does not match the API schema. - - options.webpackImporter should be a boolean. + - options.webpackImporter should be one of these: + boolean | "only" -> Enables/Disables default \`webpack\` importer. - -> Read more at https://github.com/webpack-contrib/less-loader#webpackimporter" + -> Read more at https://github.com/webpack-contrib/less-loader#webpackimporter + Details: + * options.webpackImporter should be a boolean. + * options.webpackImporter should be "only"." `; diff --git a/test/__snapshots__/webpackImporter-options.test.js.snap b/test/__snapshots__/webpackImporter-options.test.js.snap index c220944..ee3151a 100644 --- a/test/__snapshots__/webpackImporter-options.test.js.snap +++ b/test/__snapshots__/webpackImporter-options.test.js.snap @@ -36,6 +36,26 @@ exports[`"webpackImporter" option should work when value is "false": errors 1`] exports[`"webpackImporter" option should work when value is "false": warnings 1`] = `[]`; +exports[`"webpackImporter" option should work when value is "only": css 1`] = ` +"@import "some/css.css"; +@import "some/css.css"; +#it-works { + color: hotpink; +} +.modules-dir-some-module, +#it-works { + background: hotpink; +} +#it-works { + margin: 10px; +} +" +`; + +exports[`"webpackImporter" option should work when value is "only": errors 1`] = `[]`; + +exports[`"webpackImporter" option should work when value is "only": warnings 1`] = `[]`; + exports[`"webpackImporter" option should work when value is "true": css 1`] = ` "@import "some/css.css"; @import "some/css.css"; diff --git a/test/validate-options.test.js b/test/validate-options.test.js index c49be48..4664125 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -22,7 +22,7 @@ describe("validate options", () => { failure: ["string"], }, webpackImporter: { - success: [true, false], + success: [true, false, "only"], failure: ["string"], }, implementation: { diff --git a/test/webpackImporter-options.test.js b/test/webpackImporter-options.test.js index d38476a..b090a54 100644 --- a/test/webpackImporter-options.test.js +++ b/test/webpackImporter-options.test.js @@ -36,6 +36,21 @@ describe('"webpackImporter" option', () => { expect(getErrors(stats)).toMatchSnapshot("errors"); }); + it('should work when value is "only"', async () => { + const testId = "./import-webpack.less"; + const compiler = getCompiler(testId, { + webpackImporter: "only", + }); + const stats = await compile(compiler); + const codeFromBundle = getCodeFromBundle(stats, compiler); + const codeFromLess = await getCodeFromLess(testId); + + expect(codeFromBundle.css).toBe(codeFromLess.css); + expect(codeFromBundle.css).toMatchSnapshot("css"); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); + it('should work when value is "false"', async () => { const testId = "./import.less"; const compiler = getCompiler(testId, {