CSS not generated inside `var a = function a() {...}`
Environment
- Linaria version: 4.5.4
- Bundler (+ version): Vite 4.4.7, Webpack 5.75.0
- Node.js version: v18.17.0
- OS: Windows
Description
a.js:
import {css} from '@linaria/atomic'
export const a = function a() {
return css`
background-color: red;
`
}
b.js:
import { a } from "./a";
export default function App() {
return <div className={a()}>Hello World!</div>;
}
css template string in a() will be replaced with names, but the CSS rules won't be generated.
https://github.com/callstack/linaria/blob/79557248f51f21663729add3a0564a830d8d4c87/packages/babel/src/utils/getTagProcessor.ts#L394-L421
parent is the const a node, but path.scope.getBinding(id.node.name) returns the function a() node. function a() node has no references so CSS extraction was skipped.
This code is simplified from an output of Solid.js babel plugin, so it can't change.
Reproducible Demo
https://codesandbox.io/p/sandbox/interesting-brook-vn8dgp
The actual code given to Linaria is:
Expand
import { template as _$template } from "solid-js/web";
import { className as _$className } from "solid-js/web";
import { getNextMarker as _$getNextMarker } from "solid-js/web";
import { createComponent as _$createComponent } from "solid-js/web";
import { getNextElement as _$getNextElement } from "solid-js/web";
import { insert as _$insert } from "solid-js/web";
import { effect as _$effect } from "solid-js/web";
import { setAttribute as _$setAttribute } from "solid-js/web";
import { $$component as _$$component } from "solid-refresh";
import { $$refresh as _$$refresh } from "solid-refresh";
import { $$registry as _$$registry } from "solid-refresh";
const _REGISTRY = _$$registry();
const _tmpl$ = /*#__PURE__*/_$template(`<option disabled hidden selected>`),
_tmpl$2 = /*#__PURE__*/_$template(`<label><!#><!/><div><select><!#><!/><!#><!/></select><!#><!/>`);
import { css, cx } from "@linaria/atomic";
import { Show, createUniqueId } from "solid-js";
import { rem, theme } from "~/utils/theme";
import { AddClassList, FluentChevronDown16Regular } from "./icons";
export const Select = _$$component(_REGISTRY, "Select", function Select(props) {
const id = createUniqueId();
return (() => {
const _el$ = _$getNextElement(_tmpl$2),
_el$11 = _el$.firstChild,
[_el$12, _co$4] = _$getNextMarker(_el$11.nextSibling),
_el$2 = _el$12.nextSibling,
_el$3 = _el$2.firstChild,
_el$5 = _el$3.firstChild,
[_el$6, _co$] = _$getNextMarker(_el$5.nextSibling),
_el$7 = _el$6.nextSibling,
[_el$8, _co$2] = _$getNextMarker(_el$7.nextSibling),
_el$9 = _el$3.nextSibling,
[_el$10, _co$3] = _$getNextMarker(_el$9.nextSibling);
_$setAttribute(_el$, "for", id);
_$insert(_el$, () => props.label, _el$12, _co$4);
_el$3.addEventListener("change", e => props.onChange(e.currentTarget.value));
_$setAttribute(_el$3, "id", id);
_$insert(_el$3, _$createComponent(Show, {
get when() {
return props.placeholder;
},
get children() {
const _el$4 = _$getNextElement(_tmpl$);
_$insert(_el$4, () => props.placeholder);
return _el$4;
}
}), _el$6, _co$);
_$insert(_el$3, _$createComponent(AddClassList, {
get ["class"]() {
return css`
background-color: var(${theme.background});
color: var(${theme.foreground});
`;
},
get children() {
return props.children;
}
}), _el$8, _co$2);
_$insert(_el$2, _$createComponent(FluentChevronDown16Regular, {
get ["class"]() {
return css`
position: absolute;
top: 50%;
right: ${rem(8)};
transform: translateY(-50%);
font-size: ${rem(16)};
pointer-events: none;
`;
}
}), _el$10, _co$3);
_$effect(_p$ => {
const _v$ = cx(css`
color: var(${theme.foreground});
`, props.class),
_v$2 = css`
position: relative;
margin-top: ${rem(8)};
`,
_v$3 = css`
appearance: none;
display: block;
width: 100%;
height: ${rem(40)};
background-color: transparent;
border-width: 1px;
border-style: solid;
border-color: var(${theme.foreground3});
padding-left: ${rem(12)};
padding-right: ${rem(12)};
color: inherit;
border-radius: 5px;
`;
_v$ !== _p$._v$ && _$className(_el$, _p$._v$ = _v$);
_v$2 !== _p$._v$2 && _$className(_el$2, _p$._v$2 = _v$2);
_v$3 !== _p$._v$3 && _$className(_el$3, _p$._v$3 = _v$3);
return _p$;
}, {
_v$: undefined,
_v$2: undefined,
_v$3: undefined
});
_$effect(() => _el$3.value = props.value);
return _el$;
})();
}, {
location: "src\\components\\select.tsx:15:7"
});
if (import.meta.hot) {
_$$refresh("vite", import.meta.hot, _REGISTRY);
import.meta.hot.accept();
}
Two styles in get ["class"]() functions are not extracted. Styles in _$effect function are extracted correctly.
I can't share the whole project.
This issue is still reproducible with Linaria v5 (@linaria/[email protected]).
Updated demo: https://codesandbox.io/p/sandbox/elastic-water-4wwgmy