Skip to content

Commit 1399707

Browse files
committed
feat: return the [folder] template
Closes #1371
1 parent aea023d commit 1399707

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

src/utils.js

+35-10
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,30 @@ function escapeLocalIdent(localident) {
311311
);
312312
}
313313

314+
function resolveFolderTemplate(loaderContext, localIdentName, options) {
315+
const { context } = options;
316+
let { resourcePath } = loaderContext;
317+
const parsed = path.parse(loaderContext.resourcePath);
318+
319+
if (parsed.dir) {
320+
resourcePath = parsed.dir + path.sep;
321+
}
322+
323+
let directory = path
324+
.relative(context, `${resourcePath}_`)
325+
.replace(/\\/g, "/")
326+
.replace(/\.\.(\/)?/g, "_$1");
327+
directory = directory.substr(0, directory.length - 1);
328+
329+
let folder = "";
330+
331+
if (directory.length > 1) {
332+
folder = path.basename(directory);
333+
}
334+
335+
return localIdentName.replace(/\[folder\]/gi, () => folder);
336+
}
337+
314338
function defaultGetLocalIdent(
315339
loaderContext,
316340
localIdentName,
@@ -387,19 +411,20 @@ function defaultGetLocalIdent(
387411
};
388412

389413
// eslint-disable-next-line no-underscore-dangle
390-
let result = loaderContext._compilation.getPath(localIdentName, data);
391-
392-
if (options.regExp) {
393-
const match = loaderContext.resourcePath.match(options.regExp);
414+
let interpolatedFilename = loaderContext._compilation.getPath(
415+
localIdentName,
416+
data
417+
);
394418

395-
if (match) {
396-
match.forEach((matched, i) => {
397-
result = result.replace(new RegExp(`\\[${i}\\]`, "ig"), matched);
398-
});
399-
}
419+
if (localIdentName.includes("[folder]")) {
420+
interpolatedFilename = resolveFolderTemplate(
421+
loaderContext,
422+
interpolatedFilename,
423+
options
424+
);
400425
}
401426

402-
return result;
427+
return interpolatedFilename;
403428
}
404429

405430
function fixedEncodeURIComponent(str) {

test/modules-option.test.js

+40
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,46 @@ describe('"modules" option', () => {
19091909
expect(getErrors(stats)).toMatchSnapshot("errors");
19101910
});
19111911

1912+
it("should work with [folder]", async () => {
1913+
const compiler = getCompiler("./modules/localIdentName/localIdentName.js", {
1914+
modules: { localIdentName: "[local]-[folder]-[name]" },
1915+
});
1916+
const stats = await compile(compiler);
1917+
1918+
expect(
1919+
getModuleSource("./modules/localIdentName/localIdentName.css", stats)
1920+
).toMatchSnapshot("module");
1921+
expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot(
1922+
"result"
1923+
);
1924+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
1925+
expect(getErrors(stats)).toMatchSnapshot("errors");
1926+
});
1927+
1928+
it("should work with [folder] 2", async () => {
1929+
const compiler = getCompiler("./modules/localIdentName/localIdentName.js", {
1930+
modules: {
1931+
localIdentName: "[local]-[folder][name]",
1932+
localIdentContext: path.resolve(
1933+
__dirname,
1934+
"fixtures",
1935+
"modules",
1936+
"localIdentName"
1937+
),
1938+
},
1939+
});
1940+
const stats = await compile(compiler);
1941+
1942+
expect(
1943+
getModuleSource("./modules/localIdentName/localIdentName.css", stats)
1944+
).toMatchSnapshot("module");
1945+
expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot(
1946+
"result"
1947+
);
1948+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
1949+
expect(getErrors(stats)).toMatchSnapshot("errors");
1950+
});
1951+
19121952
it('should work and prefer relative for "composes"', async () => {
19131953
const compiler = getCompiler("./modules/prefer-relative/source.js", {
19141954
modules: { mode: "local" },

0 commit comments

Comments
 (0)