Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(css parser): handle nested atRule #15812

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 37 additions & 13 deletions examples/css/README.md
Expand Up @@ -34,7 +34,7 @@ body {
\*************************/
/*! default exports */
/*! exports [not provided] [no usage info] */
/*! runtime requirements: module, __webpack_require__.p, __webpack_require__.* */
/*! runtime requirements: __webpack_require__.p, module, __webpack_require__.* */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__.p + "89a353e9c515885abd8e.png";
Expand Down Expand Up @@ -437,6 +437,18 @@ body {
color: darkblue;
}

@media (min-width: 1024px) {
.app-6-main {
color: green;
}
}

@supports (display: grid) {
.app-6-main {
display: grid
}
}

head{--webpack-app-0:_4,_2,_1,_5,large%main/_6;}
```

Expand Down Expand Up @@ -469,6 +481,18 @@ body {
color: darkblue;
}

@media (min-width: 1024px) {
.app-491-D {
color: green;
}
}

@supports (display: grid) {
.app-491-D {
display: grid
}
}

head{--webpack-app-179:_548,_431,_258,_268,b%D/_491;}
```

Expand All @@ -487,16 +511,16 @@ head{--webpack-app-1:_7;}
## Unoptimized

```
assets by chunk 16.9 KiB (name: main)
assets by chunk 17 KiB (name: main)
asset output.js 16.5 KiB [emitted] (name: main)
asset output.css 385 bytes [emitted] (name: main)
asset output.css 520 bytes [emitted] (name: main)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main)
asset 1.output.css 49 bytes [emitted]
Entrypoint main 16.9 KiB (14.6 KiB) = output.js 16.5 KiB output.css 385 bytes 1 auxiliary asset
chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 335 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered]
Entrypoint main 17 KiB (14.6 KiB) = output.js 16.5 KiB output.css 520 bytes 1 auxiliary asset
chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 458 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered]
> ./example.js main
runtime modules 10 KiB 9 modules
dependent modules 42 bytes (javascript) 14.6 KiB (asset) 335 bytes (css) 42 bytes (css-import) [dependent] 6 modules
dependent modules 42 bytes (javascript) 14.6 KiB (asset) 458 bytes (css) 42 bytes (css-import) [dependent] 6 modules
./example.js 176 bytes [built] [code generated]
[no exports]
[used exports unknown]
Expand All @@ -507,30 +531,30 @@ chunk (runtime: main) 1.output.css 23 bytes
[no exports]
[used exports unknown]
import() ./lazy-style.css ./example.js 4:0-26
webpack 5.66.0 compiled successfully
webpack 5.72.0 compiled successfully
```

## Production mode

```
assets by chunk 4.25 KiB (name: main)
assets by chunk 4.38 KiB (name: main)
asset output.js 3.87 KiB [emitted] [minimized] (name: main)
asset output.css 385 bytes [emitted] (name: main)
asset output.css 518 bytes [emitted] (name: main)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main)
asset 159.output.css 53 bytes [emitted]
Entrypoint main 4.25 KiB (14.6 KiB) = output.js 3.87 KiB output.css 385 bytes 1 auxiliary asset
Entrypoint main 4.38 KiB (14.6 KiB) = output.js 3.87 KiB output.css 518 bytes 1 auxiliary asset
chunk (runtime: main) 159.output.css 23 bytes
> ./lazy-style.css ./example.js 4:0-26
./lazy-style.css 23 bytes [built] [code generated]
[no exports]
import() ./lazy-style.css ./example.js 4:0-26
chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 335 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered]
chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 458 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered]
> ./example.js main
runtime modules 10 KiB 9 modules
dependent modules 42 bytes (javascript) 14.6 KiB (asset) 335 bytes (css) 42 bytes (css-import) [dependent] 6 modules
dependent modules 42 bytes (javascript) 14.6 KiB (asset) 458 bytes (css) 42 bytes (css-import) [dependent] 6 modules
./example.js 176 bytes [built] [code generated]
[no exports]
[no exports used]
entry ./example.js main
webpack 5.66.0 compiled successfully
webpack 5.72.0 compiled successfully
```
12 changes: 12 additions & 0 deletions examples/css/style.module.css
Expand Up @@ -6,3 +6,15 @@
font-size: var(--large);
color: darkblue;
}

@media (min-width: 1024px) {
.main {
color: green;
}
}

@supports (display: grid) {
.main {
display: grid
}
}
13 changes: 13 additions & 0 deletions lib/css/CssParser.js
Expand Up @@ -296,6 +296,7 @@ class CssParser extends Parser {
module.addDependency(dep);
}
};
const eatAtRuleNested = eatUntil("{};/");
const eatKeyframes = eatUntil("{};/");
const eatNameInVar = eatUntil(",)};/");
walkCssTokens(source, {
Expand Down Expand Up @@ -380,6 +381,18 @@ class CssParser extends Parser {
modeNestingLevel = 1;
return pos + 1;
}
if (name === "@media" || name === "@supports") {
let pos = end;
const [newPos] = eatText(input, pos, eatAtRuleNested);
pos = newPos;
if (pos === input.length) return pos;
if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
throw new Error(
`Unexpected ${input[pos]} at ${pos} during parsing of @media or @supports (expected '{')`
);
}
return pos + 1;
}
return end;
},
semicolon: (input, start, end) => {
Expand Down
20 changes: 19 additions & 1 deletion test/configCases/css/css-modules-in-node/index.js
Expand Up @@ -20,7 +20,25 @@ it("should allow to create css modules", done => {
animation: prod ? "my-app-491-oQ" : "./style.module.css-animation",
vars: prod
? "--my-app-491-y4 my-app-491-gR undefined my-app-491-xk"
: "--./style.module.css-local-color ./style.module.css-vars undefined ./style.module.css-globalVars"
: "--./style.module.css-local-color ./style.module.css-vars undefined ./style.module.css-globalVars",
media: prod
? "my-app-491-w7"
: "./style.module.css-wideScreenClass",
mediaWithOperator: prod
? "my-app-491-J"
: "./style.module.css-narrowScreenClass",
supports: prod
? "my-app-491-T$"
: "./style.module.css-displayGridInSupports",
supportsWithOperator: prod
? "my-app-491-zz"
: "./style.module.css-floatRightInNegativeSupports",
mediaInSupports: prod
? "my-app-491-Kr"
: "./style.module.css-displayFlexInMediaInSupports",
supportsInMedia: prod
? "my-app-491-SQ"
: "./style.module.css-displayFlexInSupportsInMedia",
});
} catch (e) {
return done(e);
Expand Down
20 changes: 19 additions & 1 deletion test/configCases/css/css-modules/index.js
Expand Up @@ -23,7 +23,25 @@ it("should allow to create css modules", done => {
animation: prod ? "my-app-491-oQ" : "./style.module.css-animation",
vars: prod
? "--my-app-491-y4 my-app-491-gR undefined my-app-491-xk"
: "--./style.module.css-local-color ./style.module.css-vars undefined ./style.module.css-globalVars"
: "--./style.module.css-local-color ./style.module.css-vars undefined ./style.module.css-globalVars",
media: prod
? "my-app-491-w7"
: "./style.module.css-wideScreenClass",
mediaWithOperator: prod
? "my-app-491-J"
: "./style.module.css-narrowScreenClass",
supports: prod
? "my-app-491-T$"
: "./style.module.css-displayGridInSupports",
supportsWithOperator: prod
? "my-app-491-zz"
: "./style.module.css-floatRightInNegativeSupports",
mediaInSupports: prod
? "my-app-491-Kr"
: "./style.module.css-displayFlexInMediaInSupports",
supportsInMedia: prod
? "my-app-491-SQ"
: "./style.module.css-displayFlexInSupportsInMedia",
});
} catch (e) {
return done(e);
Expand Down
42 changes: 42 additions & 0 deletions test/configCases/css/css-modules/style.module.css
Expand Up @@ -69,3 +69,45 @@
color: var(--global-color);
--global-color: red;
}

@media (min-width: 1600px) {
.wideScreenClass {
color: var(--local-color);
--local-color: green;
}
}

@media screen and (max-width: 600px) {
.narrowScreenClass {
color: var(--local-color);
--local-color: purple;
}
}

@supports (display: grid) {
.displayGridInSupports {
display: grid;
}
}

@supports not (display: grid) {
.floatRightInNegativeSupports {
float: right;
}
}

@supports (display: flex) {
@media screen and (min-width: 900px) {
.displayFlexInMediaInSupports {
display: flex;
}
}
}

@media screen and (min-width: 900px) {
@supports (display: flex) {
.displayFlexInSupportsInMedia {
display: flex;
}
}
}
8 changes: 7 additions & 1 deletion test/configCases/css/css-modules/use-style.js
Expand Up @@ -10,5 +10,11 @@ export default {
ident,
keyframes: style.localkeyframes,
animation: style.animation,
vars: `${style["local-color"]} ${style.vars} ${style["global-color"]} ${style.globalVars}`
vars: `${style["local-color"]} ${style.vars} ${style["global-color"]} ${style.globalVars}`,
media: style.wideScreenClass,
mediaWithOperator: style.narrowScreenClass,
supports: style.displayGridInSupports,
supportsWithOperator: style.floatRightInNegativeSupports,
mediaInSupports: style.displayFlexInMediaInSupports,
supportsInMedia: style.displayFlexInSupportsInMedia,
};
2 changes: 1 addition & 1 deletion test/configCases/css/large/index.js
Expand Up @@ -8,7 +8,7 @@ it("should allow to create css modules", done => {
try {
expect(x).toEqual({
placeholder: prod
? "26-uhH"
? "26-uhHx"
: "my-app-./tailwind.module.css-placeholder-gray-700"
});
} catch (e) {
Expand Down