From 13997078bb3a5cc244c8f0839d48b11e38fc6470 Mon Sep 17 00:00:00 2001 From: Igor Zvyagintsev Date: Tue, 14 Sep 2021 20:58:28 +0300 Subject: [PATCH 1/2] feat: return the [folder] template Closes #1371 --- src/utils.js | 45 ++++++++++++++++++++++++++++--------- test/modules-option.test.js | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/utils.js b/src/utils.js index a674bfb3..e7d014e9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -311,6 +311,30 @@ function escapeLocalIdent(localident) { ); } +function resolveFolderTemplate(loaderContext, localIdentName, options) { + const { context } = options; + let { resourcePath } = loaderContext; + const parsed = path.parse(loaderContext.resourcePath); + + if (parsed.dir) { + resourcePath = parsed.dir + path.sep; + } + + let directory = path + .relative(context, `${resourcePath}_`) + .replace(/\\/g, "/") + .replace(/\.\.(\/)?/g, "_$1"); + directory = directory.substr(0, directory.length - 1); + + let folder = ""; + + if (directory.length > 1) { + folder = path.basename(directory); + } + + return localIdentName.replace(/\[folder\]/gi, () => folder); +} + function defaultGetLocalIdent( loaderContext, localIdentName, @@ -387,19 +411,20 @@ function defaultGetLocalIdent( }; // eslint-disable-next-line no-underscore-dangle - let result = loaderContext._compilation.getPath(localIdentName, data); - - if (options.regExp) { - const match = loaderContext.resourcePath.match(options.regExp); + let interpolatedFilename = loaderContext._compilation.getPath( + localIdentName, + data + ); - if (match) { - match.forEach((matched, i) => { - result = result.replace(new RegExp(`\\[${i}\\]`, "ig"), matched); - }); - } + if (localIdentName.includes("[folder]")) { + interpolatedFilename = resolveFolderTemplate( + loaderContext, + interpolatedFilename, + options + ); } - return result; + return interpolatedFilename; } function fixedEncodeURIComponent(str) { diff --git a/test/modules-option.test.js b/test/modules-option.test.js index d658af16..2e92b094 100644 --- a/test/modules-option.test.js +++ b/test/modules-option.test.js @@ -1909,6 +1909,46 @@ describe('"modules" option', () => { expect(getErrors(stats)).toMatchSnapshot("errors"); }); + it("should work with [folder]", async () => { + const compiler = getCompiler("./modules/localIdentName/localIdentName.js", { + modules: { localIdentName: "[local]-[folder]-[name]" }, + }); + const stats = await compile(compiler); + + expect( + getModuleSource("./modules/localIdentName/localIdentName.css", stats) + ).toMatchSnapshot("module"); + expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot( + "result" + ); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); + + it("should work with [folder] 2", async () => { + const compiler = getCompiler("./modules/localIdentName/localIdentName.js", { + modules: { + localIdentName: "[local]-[folder][name]", + localIdentContext: path.resolve( + __dirname, + "fixtures", + "modules", + "localIdentName" + ), + }, + }); + const stats = await compile(compiler); + + expect( + getModuleSource("./modules/localIdentName/localIdentName.css", stats) + ).toMatchSnapshot("module"); + expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot( + "result" + ); + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); + it('should work and prefer relative for "composes"', async () => { const compiler = getCompiler("./modules/prefer-relative/source.js", { modules: { mode: "local" }, From 66132f9a19743bb63ca2f26dd9d9f1ef51073156 Mon Sep 17 00:00:00 2001 From: Igor Zvyagintsev Date: Wed, 15 Sep 2021 17:14:17 +0300 Subject: [PATCH 2/2] feat: return the [folder] template return code accidentally removed Closes #1371 --- src/utils.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/utils.js b/src/utils.js index e7d014e9..88e84186 100644 --- a/src/utils.js +++ b/src/utils.js @@ -416,6 +416,19 @@ function defaultGetLocalIdent( data ); + if (options.regExp) { + const match = loaderContext.resourcePath.match(options.regExp); + + if (match) { + match.forEach((matched, i) => { + interpolatedFilename = interpolatedFilename.replace( + new RegExp(`\\[${i}\\]`, "ig"), + matched + ); + }); + } + } + if (localIdentName.includes("[folder]")) { interpolatedFilename = resolveFolderTemplate( loaderContext,