compiled
compiled copied to clipboard
When using an object property in a media query, `as const` in the object definition causes build to fail
The following code fails with a Cannot statically evaluate the value of "MemberExpression
error:
import { styled } from '@compiled/react';
import React from 'react';
const media = {
from: {
fromMobile: '@media (min-width: 30em)',
},
} as const;
const SummaryContainer = styled.div({
[media.from.fromMobile]: {
color: 'blue',
}
});
export const App = (): JSX.Element => (
<>
<SummaryContainer>Goodbye world?</SummaryContainer>
</>
);
Removing as const
resolves the error.
This is because @compiled/babel-plugin
is not able to handle the TSAsExpression
node when traversing the Babel AST. TSAsExpression
is the node Babel uses to represent the { ... } as const
syntax.
Note that as const
can appear anywhere in an object, so we need to handle stuff like this too:
const media = {
from: {
fromMobile: '@media (min-width: 30em)',
} as const,
};
These are the files that need to be updated to support the { ... } as const
syntax (there might be more):
- https://github.com/atlassian-labs/compiled/blob/5a5ab2eb6be8d9f1c3aa33c11e897ba70433cdb1/packages/babel-plugin/src/utils/traverse-expression/traverse-member-expression/traverse-access-path/evaluate-path/index.ts#L14
- https://github.com/atlassian-labs/compiled/blob/41bcb1eb8b288c5c6f4a625db87c1f8969eda5ae/packages/babel-plugin/src/utils/traversers/object.ts#L6
Workaround
You can try using readonly
instead of as const
. It's kind of awkward for large variables, but it avoids the errors:
type MediaType = {
readonly from: { readonly fromMobile: string },
}
export const media: MediaType = {
from: {
fromMobile: '@media (min-width: 30em)',
},
};