Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ function getLocalIdent(loaderContext, localIdentName, localName, options) {
);

return hash
.replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-')
.replace(/\\@/g, '@')
.replace(new RegExp('[^a-zA-Z0-9@\\-_\u00A0-\uFFFF]', 'g'), '-')
.replace(/^((-?[0-9])|--)/, '_$1');
}

Expand Down
99 changes: 92 additions & 7 deletions test/__snapshots__/localIdentName-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
Expand Down Expand Up @@ -78,7 +82,11 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
Expand Down Expand Up @@ -121,7 +129,11 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
Expand Down Expand Up @@ -164,7 +176,11 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
Expand Down Expand Up @@ -207,7 +223,11 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
Expand Down Expand Up @@ -250,7 +270,11 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
Expand Down Expand Up @@ -293,10 +317,71 @@ Array [
:local(.-a0-34a___f) {
color: red;
}
",

:local(.m_x_\\\\@) {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
`;

exports[`localIdentName option should use hash prefix: warnings 1`] = `Array []`;

exports[`localIdentName option should сorrectly replace symbol @ in selector: errors 1`] = `Array []`;

exports[`localIdentName option should сorrectly replace symbol @ in selector: locals 1`] = `
Object {
"-a0-34a___f": "-a0-34a___f--2nJ5",
"_test": "_test--23te",
"className": "className--1E8H",
"m_x_@": "m_x_@--2G3b",
"someId": "someId--3w7J",
"subClass": "subClass--3lo0",
"test": "test--NW9Y",
}
`;

exports[`localIdentName option should сorrectly replace symbol @ in selector: module (evaluated) 1`] = `
Array [
Array [
1,
".test--NW9Y {
background: red;
}

._test--23te {
background: blue;
}

.className--1E8H {
background: red;
}

#someId--3w7J {
background: green;
}

.className--1E8H .subClass--3lo0 {
color: green;
}

#someId--3w7J .subClass--3lo0 {
color: blue;
}

.-a0-34a___f--2nJ5 {
color: red;
}

.m_x_@--2G3b {
margin-left: auto !important;
margin-right: auto !important;
}",
"",
],
]
`;

exports[`localIdentName option should сorrectly replace symbol @ in selector: warnings 1`] = `Array []`;
5 changes: 5 additions & 0 deletions test/fixtures/modules/localIdentName.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@
:local(.-a0-34a___f) {
color: red;
}

:local(.m_x_\@) {
margin-left: auto !important;
margin-right: auto !important;
}
24 changes: 24 additions & 0 deletions test/localIdentName-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,28 @@ describe('localIdentName option', () => {
expect(stats.compilation.warnings).toMatchSnapshot('warnings');
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

it('should сorrectly replace symbol @ in selector', async () => {
const config = {
loader: {
options: {
importLoaders: 2,
localIdentName: '[local]--[hash:base64:4]',
modules: true,
},
},
};
const testId = './modules/localIdentName.css';
const stats = await webpack(testId, config);
const { modules } = stats.toJson();
const module = modules.find((m) => m.id === testId);
const evaluatedModule = evaluated(module.source, modules);

expect(evaluatedModule.locals['m_x_@']).toContain('m_x_@');

expect(evaluatedModule).toMatchSnapshot('module (evaluated)');
expect(evaluatedModule.locals).toMatchSnapshot('locals');
expect(stats.compilation.warnings).toMatchSnapshot('warnings');
expect(stats.compilation.errors).toMatchSnapshot('errors');
});
});