babel-plugin-styled-components icon indicating copy to clipboard operation
babel-plugin-styled-components copied to clipboard

1.13.2 generates cannot read property 'property' of undefined

Open Kolombiken opened this issue 4 years ago • 19 comments

I'm using Next.js and when trying 1.13.2 I get the following webpack-error for a component:

TypeError: Form.tsx: Cannot read property 'property' of undefined

The only css in the component are three declarations looking like this:

const StyledFormComponent = styled.divdisplay: flex;;

With 1.13.1 there are no errors.

Kolombiken avatar Jul 09 '21 11:07 Kolombiken

Going to need some sort of reproduction

quantizor avatar Jul 09 '21 21:07 quantizor

I am getting something similar when using an object as a css value <div css={{ position: 'relative', zIndex: 1 }}> Cannot read property 'toString' of undefined

but if I extract the value like this

const zIndex = 1
  return (
    <div css={{ position: 'relative', zIndex }}>

then it is not complaining

and it is only failing with zIndex, no issues with position

I've tried last version 1.13.2 and 1.12.0

ivan-navarro-75 avatar Jul 12 '21 15:07 ivan-navarro-75

Same here,

TypeError: components/Button.js: Cannot read property 'property' of undefined
      at node_modules/babel-plugin-styled-components/lib/utils/detectors.js:85:686
      at node_modules/babel-plugin-styled-components/lib/visitors/pure.js:18:36
      at PluginPass.CallExpression (node_modules/babel-plugin-styled-components/lib/index.js:45:30)
      at newFn (node_modules/@babel/traverse/lib/visitors.js:171:21)

Wonder if it is an issue with the way TS converts template literals, as the outputted code is:

var StyledButton = styled_components_1.default.button(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n  ", ";\n"], ["\n  ", ";\n"])), getButtonStyles_1.default);
StyledButton.displayName = 'StyledButton';
// Target the <a> here to override a:hover specificity.
var StyledLink = styled_components_1.default.a(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n  a& {\n    ", ";\n  }\n"], ["\n  a& {\n    ", ";\n  }\n"])), getButtonStyles_1.default);
StyledLink.displayName = 'StyledLink';
var StyledSpan = styled_components_1.default.span(templateObject_3 || (templateObject_3 = tslib_1.__makeTemplateObject(["\n  ", ";\n"], ["\n  ", ";\n"])), getButtonStyles_1.default);
StyledSpan.displayName = 'StyledSpan';

albertogasparin avatar Sep 01 '21 23:09 albertogasparin

Oh, btw found a workaround: setting "pure": false skips the code path that blows up

albertogasparin avatar Sep 02 '21 01:09 albertogasparin

Same here,

TypeError: components/Button.js: Cannot read property 'property' of undefined
      at node_modules/babel-plugin-styled-components/lib/utils/detectors.js:85:686
      at node_modules/babel-plugin-styled-components/lib/visitors/pure.js:18:36
      at PluginPass.CallExpression (node_modules/babel-plugin-styled-components/lib/index.js:45:30)
      at newFn (node_modules/@babel/traverse/lib/visitors.js:171:21)

Wonder if it is an issue with the way TS converts template literals, as the outputted code is:

var StyledButton = styled_components_1.default.button(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n  ", ";\n"], ["\n  ", ";\n"])), getButtonStyles_1.default);
StyledButton.displayName = 'StyledButton';
// Target the <a> here to override a:hover specificity.
var StyledLink = styled_components_1.default.a(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n  a& {\n    ", ";\n  }\n"], ["\n  a& {\n    ", ";\n  }\n"])), getButtonStyles_1.default);
StyledLink.displayName = 'StyledLink';
var StyledSpan = styled_components_1.default.span(templateObject_3 || (templateObject_3 = tslib_1.__makeTemplateObject(["\n  ", ";\n"], ["\n  ", ";\n"])), getButtonStyles_1.default);
StyledSpan.displayName = 'StyledSpan';

Can you post the code that leads to this error so I can make a test case for it? Ty.

quantizor avatar Sep 02 '21 17:09 quantizor

I am also facing the same issue. To reproduce the issue you can checkout this branch feat/use-medly-linting-configs of https://github.com/medly/medly-components and then run yarn build & yarn test. For a quick glance below is the error I am getting.

Error

TypeError: /Users/mukul/workspace/medly-open-source/medly-components/packages/icons/dist/cjs/SvgIcon/SvgIcon.styled.js: Cannot read property 'property' of undefined

      at node_modules/babel-plugin-styled-components/lib/utils/detectors.js:85:686
      at node_modules/babel-plugin-styled-components/lib/utils/detectors.js:71:25
      at node_modules/babel-plugin-styled-components/lib/utils/detectors.js:71:25
      at node_modules/babel-plugin-styled-components/lib/visitors/displayNameAndId.js:158:30
      at PluginPass.CallExpression (node_modules/babel-plugin-styled-components/lib/index.js:44:42)
      at newFn (node_modules/@babel/traverse/lib/visitors.js:177:21)
      at NodePath._call (node_modules/@babel/traverse/lib/path/context.js:53:20)
      at NodePath.call (node_modules/@babel/traverse/lib/path/context.js:40:17)
      at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:90:31)
      at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:103:16)

dist/cjs/SvgIcon/SvgIcon.styled.js

'use strict';
Object.defineProperty(exports, '__esModule', { value: !0 });
var o = require('@medly-components/utils'),
    r = require('styled-components');
function e(o) {
    return o && 'object' == typeof o && 'default' in o ? o : { default: o };
}
var n = function (o) {
        var e = o.hoverBgColor,
            n = o.hoverIconColor;
        return r.css(
            ['&:hover{background-color:', ';*{fill:', ';}}'],
            function (o) {
                var r = o.theme;
                return e || r.icon.colors.hovered.bgColor;
            },
            function (o) {
                var r = o.theme;
                return n || r.icon.colors.hovered.iconColor;
            }
        );
    },
    i = function (o) {
        var e = o.size,
            i = o.disabled,
            t = o.bgColor,
            l = o.withHoverEffect;
        return r.css(
            ['padding:', ';border-radius:', ';background-color:', ';', ''],
            function (o) {
                return o.theme.icon.sizes[e].padding;
            },
            function (o) {
                return o.theme.icon.borderRadius;
            },
            function (o) {
                var r = o.theme;
                return i ? r.icon.colors.disabled.bgColor : t || r.icon.colors.default.bgColor;
            },
            !i && l && n
        );
    },
    t = e(r)
        .default(o.InjectClassName)
        .attrs(function (o) {
            var r = o.theme.icon;
            return { colors: r.colors, sizes: r.sizes };
        })
        .withConfig({ displayName: 'SvgIconstyled__SvgIconStyled', componentId: 'sc-1pf3x8a-0' })(
        [
            'overflow:visible;font-size:',
            ';transition:all 100ms linear;margin:',
            ';cursor:',
            ';*{fill-opacity:',
            ';transition:all 100ms linear;fill:',
            ';}',
            ''
        ],
        function (o) {
            var r = o.theme,
                e = o.size;
            return r.icon.sizes[e].iconSize;
        },
        function (o) {
            return o.margin;
        },
        function (o) {
            var r = o.onClick;
            return o.disabled ? 'not-allowed' : r ? 'pointer' : 'inherit';
        },
        function (o) {
            return o.fillOpacity;
        },
        function (o) {
            var r = o.disabled,
                e = o.colors,
                n = o.iconColor;
            return r ? e.disabled.iconColor : n || e.default.iconColor;
        },
        function (o) {
            return 'solid' === o.variant && i;
        }
    );
(t.displayName = 'SvgIcon'), (t.defaultProps = { size: 'M', fillOpacity: 1 }), (exports.SvgIconStyled = t);

SVGIcon.styled.tsx

import { InjectClassName } from '@medly-components/utils';
import styled, { css } from 'styled-components';
import { SvgIconProps } from './types';

const hoverStyle = ({ hoverBgColor, hoverIconColor }: SvgIconProps) => css`
    &:hover {
        background-color: ${({ theme }) => hoverBgColor || theme.icon.colors.hovered.bgColor};
        * {
            fill: ${({ theme }) => hoverIconColor || theme.icon.colors.hovered.iconColor};
        }
    }
`;

const solidStyle = ({ size, disabled, bgColor, withHoverEffect }: SvgIconProps) => css`
    padding: ${({ theme }) => theme.icon.sizes[size!].padding};
    border-radius: ${({ theme }) => theme.icon.borderRadius};
    background-color: ${({ theme }) => (disabled ? theme.icon.colors.disabled.bgColor : bgColor || theme.icon.colors.default.bgColor)};

    ${!disabled && withHoverEffect && hoverStyle}
`;

export const SvgIconStyled = styled(InjectClassName).attrs(
    ({
        theme: {
            icon: { colors, sizes }
        }
    }) => ({
        colors,
        sizes
    })
)<SvgIconProps>`
    overflow: visible;
    font-size: ${({ theme, size }) => theme.icon.sizes[size!].iconSize};
    transition: all 100ms linear;
    margin: ${({ margin }) => margin};
    cursor: ${({ onClick, disabled }) => (disabled ? 'not-allowed' : onClick ? 'pointer' : 'inherit')};
    * {
        fill-opacity: ${({ fillOpacity }) => fillOpacity};
        transition: all 100ms linear;
        fill: ${({ disabled, colors, iconColor }) => (disabled ? colors.disabled.iconColor : iconColor || colors.default.iconColor)};
    }

    ${({ variant }) => variant === 'solid' && solidStyle}
`;

SvgIconStyled.displayName = 'SvgIcon';
SvgIconStyled.defaultProps = {
    size: 'M',
    fillOpacity: 1
};

gmukul01 avatar Oct 17 '21 05:10 gmukul01

@probablyup Actually the error occurs only in files where I am using css helper.

gmukul01 avatar Oct 18 '21 11:10 gmukul01

Actually this was happening because of one of babel version. You can checkout the latest version being used in medly-components

gmukul01 avatar Oct 21 '21 14:10 gmukul01

It's still a problem in 2.0.6. Here's a simple reproduction:

import styled from "styled-components";

const WrappedComponent = styled.default()``;

You can paste that into one of your tests and it will fail. The issue is with this code in detectors.js:

(importLocalName('default', state) &&
        t.isCallExpression(tag) &&
        t.isMemberExpression(tag.callee) &&
        tag.object.property.name === 'default' &&
        tag.object.object.name === importLocalName('default', state))

tag.object is undefined. There's tag.callee in one place and tag.object in another. I assume that's the problem.

pawelczerepak avatar Feb 25 '22 21:02 pawelczerepak

@probablyup The above comment already describes the error, probably a simple copy-paste error.

I guess the correct line would be:

(importLocalName('default', state) &&
        t.isCallExpression(tag) &&
        t.isMemberExpression(tag.callee) &&
        tag.callee.property.name === 'default' &&
        tag.callee.object.name === importLocalName('default', state))

I can provide a PR if you come to the same fix/conclusion as above

Without a fix, importing minified ES6 code, which uses sc, doesn't work when the babel plugin is utilized.

JohnnyCrazy avatar Apr 13 '22 10:04 JohnnyCrazy

I'm honestly afraid to touch that code at this point. I've made updates multiple times that worked fine in testing and then caused all sorts of havoc in people's production setups :/

quantizor avatar Apr 13 '22 20:04 quantizor

Mh, understandable.

We will have to go for forking then! Thanks for keeping the project open-source so this is even possible 👍🏼

JohnnyCrazy avatar Apr 14 '22 11:04 JohnnyCrazy

Is there any update on this issue? Facing it in the latest version on a Next.js application.

tanmay-pnaik avatar Sep 29 '22 21:09 tanmay-pnaik

Is there any update on this issue? Facing it in the latest version on a Next.js application.

Turned out to be a config issue in our application.

tanmay-pnaik avatar Oct 06 '22 07:10 tanmay-pnaik

Hi tanmay-pnaik, you can say what are bad config in your app?

mauricioross avatar Oct 24 '22 04:10 mauricioross

Having the same issue w/ rollup generated code that changed from:

styled__default["default"] which works to styled__default.default which fails here.

Any update on this?

It failse for me at Cannot read properties of undefined (reading 'property') on tag.object.property because tag.object seems undefined.

andi1984 avatar Oct 25 '22 12:10 andi1984

FYI: Rollup v3 output.generatedCode.reservedNamesAsProps setting on true is not compatible with this plugin due to this bug. Thus for now whenever you generate code containing styled-components from rollup, set output.generatedCode.reservedNamesAsProps to false in rollup.

andi1984 avatar Oct 25 '22 13:10 andi1984

Adding on @andi1984 I also had added output.interop: "auto" to act the same as [email protected]: true

renarsvilnis avatar Dec 05 '22 15:12 renarsvilnis

Setting the rollup options mentioned by @andi1984 and @renarsvilnis solved this issue for us as well:

output: {
  interop: "auto",
  generatedCode: {
    reservedNamesAsProps: false,
  },
}

chaburgess avatar Jan 12 '23 16:01 chaburgess