styled-components / babel-plugin-styled-components

Improve the debugging experience and add server-side rendering support to styled-components
MIT License
1.07k stars 141 forks source link

displayName is broken since v1.10.3 #261

Open psixdev opened 4 years ago

psixdev commented 4 years ago

Hello. Starting with version 1.10.3, the plugin stops adding displayName to generated classes. This option worked in 1.10.2 and does not work in all subsequent versions. Here is a repository with a small example to verify this: https://github.com/psixdev/babel-plugin-styled-components-bug

After loading the page, I get this html: image

If I used version 1.10.2, it would be different: image

Is this a bug in the library, or is something wrong in my application?

psixdev commented 4 years ago

It seems that the plugin only works if I use import instead of require in my code. Is it possible to make the plugin work with require?

frisbee09 commented 4 years ago

This is a duplicate of #243, I think. My current suspicion is something happening inside of @babel/core

baybara-pavel commented 4 years ago

+1 for @babel/core changes In my case, broken behavior reproduced with "babel-plugin-styled-components": "1.10.2", when I adding types to sc

// styled-components.ts
import * as styledComponents from 'styled-components';

import { Theme } from 'theme';

const {
  default: styled,
  css,
  createGlobalStyle,
  keyframes,
  ThemeProvider,
} = styledComponents as styledComponents.ThemedStyledComponentsModule<Theme>;

export { css, createGlobalStyle, keyframes, ThemeProvider };
export default styled;

When I replace imports to the original lib in the target component displayName start work correctly

// import styled from 'utils/styled-components/styled-components'; <- displayName don't generates
import styled from 'styled-components'; //  <- displayName generates

In the beginning, I blame @babel/preset-typescript, but then I try to remove types and make just reexport for an experiment - nothing changed

// styled-components.js
import * as styledComponents from 'styled-components';

const { default: styled, css, createGlobalStyle, keyframes, ThemeProvider } = styledComponents;

export { css, createGlobalStyle, keyframes, ThemeProvider };
export default styled;

Then I try to add ignoring for babel transpile of my styled-components reexport file and everything start workingπŸŽ‰ (except the types actually 😞)

// babel.config.js
module.exports ={
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: [
    ['babel-plugin-styled-components', { ssr: false, displayName: true }],
    '@babel/plugin-transform-react-constant-elements',
    '@babel/plugin-proposal-export-default-from',
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }],
    '@babel/plugin-syntax-dynamic-import',
    '@babel/plugin-proposal-object-rest-spread',
    // eslint-disable-next-line no-magic-numbers
    ['@babel/plugin-transform-runtime', { corejs: 2 }],
  ],
  overrides: [
    {
      test: /\.(ts|tsx)$/,
      presets: ['@babel/preset-typescript'],
      plugins: [
        'babel-plugin-ts-optchain',
        // eslint-disable-next-line no-magic-numbers
        ['@babel/plugin-transform-runtime', { corejs: 2 }],
      ],
    },
  ],
  ignore: ['./**/styled-components.js'],
};

I think the reason in that side effect: babel transpiled my reexport file with styled-components -> some property or method in sc changing and babel-plugin-styled-components can't find the right way to add displayName and it doesn't work correctly.

And suspicion to@babel\core was proved by that config:

// babel.config.js
module.exports ={
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: [
    ['babel-plugin-styled-components', { ssr: false, displayName: true }],
  ],
};

In that case nothing work with the same simple styled-components reexport

// styled-components.js
import * as styledComponents from 'styled-components';

const { default: styled, css, createGlobalStyle, keyframes, ThemeProvider } = styledComponents;

export { css, createGlobalStyle, keyframes, ThemeProvider };
export default styled;
baybara-pavel commented 4 years ago

I found the workaround solution for that case. The reason in @babel\preset-env. Just overrides in babel config for my styled-components reexport with theme types and everything work

// babel.config.js
module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react'],
  plugins: [
    ['babel-plugin-styled-components', { ssr: false, displayName: true }],
    '@babel/plugin-transform-react-constant-elements',
    '@babel/plugin-proposal-export-default-from',
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }],
    '@babel/plugin-syntax-dynamic-import',
    '@babel/plugin-proposal-object-rest-spread',
    // eslint-disable-next-line no-magic-numbers
    ['@babel/plugin-transform-runtime', { corejs: 2 }],
  ],
  overrides: [
  // --- The Saver:
    {
      test: /styled-components\.(ts|tsx)$/,
      presets: ['@babel/preset-react', '@babel/preset-typescript'],
    },
  // ---
    {
      test: /\.(ts|tsx)$/,
      presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
      plugins: [
        'babel-plugin-ts-optchain',
        // eslint-disable-next-line no-magic-numbers
        ['@babel/plugin-transform-runtime', { corejs: 2 }],
      ],
    },
  ],
};
// styled-components.ts
import * as styledComponents from 'styled-components';

import { Theme } from 'theme';

const {
  default: styled,
  css,
  createGlobalStyle,
  keyframes,
  ThemeProvider,
} = styledComponents as styledComponents.ThemedStyledComponentsModule<Theme>;

export { css, createGlobalStyle, keyframes, ThemeProvider };
export default styled;

image

frisbee09 commented 4 years ago

I have the same snippet of typing from the styled-components documentation, I can try this override and see if it works for me also. Nice work @baybara-pavel :)

baybara-pavel commented 4 years ago

@frisbee09 I hope it helps you to πŸ™‚ Important: This workaround works only with "babel-plugin-styled-components": "1.10.2" with last 1.10.6 - still broken Thanks to https://github.com/novli for insight

frisbee09 commented 4 years ago

On further inspection, could this be broken due to #230 If the plugin is trying to detect a direct import from 'styled-components' and we're importing a "typed" re-export, we might be turning off the transpilation step inadvertently.

It might be that the plugin currently does not support a typed theme as specified in the styled-components documentation. I'll try looking into this.

This would also mean we're seeing the same issue as found in #238

nihgwu commented 4 years ago

same issue here, although we don't use typescript, we just reexported styled-components in our theme system, as pointed by @frisbee09 , it's caused by #230 , then what should we do if we still want to reexport styled-components? maybe we could provide a config to disable the check? @probablyup

ForestJohnson commented 4 years ago

If you are using something like create-react-app, try this instead: https://styled-components.com/docs/tooling#babel-macro

tshddx commented 4 years ago

Is anyone else still experiencing this? I'm not getting component displayNames in my SC classes on babel-plugin-styled-components 1.10.7.

I tried downgrading to 1.10.2 to try the overrides workaround but it seems like styled-components@^5.0.1 depends on babel-plugin-styled-components ">= 1" and yarn seems to grab the latest 1.10.7 due to that dependency (I don't understand that at all, but it's a separate issue).

joekrill commented 4 years ago

@baddox Yeah this is still affecting me. The babel macro alternative works, but I've been unable to get that to work in a mono-repo situation where my components are in a different package. Also I'm not sold on the idea of having to use a completely different import in that case.

bradtgmurray commented 4 years ago

Also running into this. Seems like I'm only running into issues when using ts-loader in my webpack config.

Example minimal repo reproducing the issue: https://github.com/bradtgmurray/babel-styled-components-test-repo

image

This branch fixes the issue by flipping from ts-loader to using babel to transpile my typescript.

https://github.com/bradtgmurray/babel-styled-components-test-repo/compare/fixed?expand=1

image

tshddx commented 4 years ago

@bradtgmurray That's really interesting. I'm not using TS at all and I have the problem. I have a minimal example built on a create-react-app in this thread: https://github.com/rebassjs/rebass/issues/434#issuecomment-606805872

rozzzly commented 4 years ago

@bradtgmurray I just created a PR (https://github.com/styled-components/babel-plugin-styled-components/pull/279) for another issue related to displayName but I'm curious if it might not resolve your issue as well.

AssisrMatheus commented 4 years ago

While using next.js. I fixed the issue by manually adding into package.json:

    "@babel/core": "7.8.4",
    "@babel/preset-env": "7.8.4",
    "babel-loader": "8.0.6",
    "babel-plugin-styled-components": "1.10.6",

This is my .babelrc.json

{
  "env": {
    "development": {
      "presets": ["next/babel"],
      "plugins": [
        [
          "babel-plugin-styled-components",
          {
            "ssr": true,
            "displayName": true,
            "fileName": false
          }
        ]
      ]
    },
    "production": {
      "presets": ["next/babel"],
      "plugins": [
        [
          "babel-plugin-styled-components",
          {
            "ssr": true,
            "displayName": true,
            "fileName": false
          }
        ]
      ]
    },
    "test": {
      "presets": [["next/babel"]],
      "plugins": [
        [
          "babel-plugin-styled-components",
          {
            "ssr": true,
            "displayName": true,
            "fileName": false
          }
        ]
      ]
    }
  }
}
mkzxcvbnm commented 4 years ago

import styled from 'styled-components' replace to import styled from 'styled-components/macro'

But I don't know what the side effects are

ChrisKuBa commented 3 years ago

Based on comparing 1.10.2 and 1.10.3 https://github.com/styled-components/babel-plugin-styled-components/compare/v1.10.2...v1.10.3

It seems that the problem starts here:

https://github.com/styled-components/babel-plugin-styled-components/blob/950692b92855f17609e4281d5081e3d2acbf4b6b/src/utils/detectors.js#L24

The local name is ignored when import statements are used and it is not cached.

https://github.com/styled-components/babel-plugin-styled-components/blob/9c4f19f104789299a4d7c4216a1abd0dbfb55bd1/src/utils/detectors.js#L13 importLocalName is used in isStyles.

https://github.com/styled-components/babel-plugin-styled-components/blob/9c4f19f104789299a4d7c4216a1abd0dbfb55bd1/src/utils/detectors.js#L58 isStyled is used here https://github.com/styled-components/babel-plugin-styled-components/blob/950692b92855f17609e4281d5081e3d2acbf4b6b/src/visitors/displayNameAndId.js#L147 and is always false in my environment, so addConfig is never called and no displayName is configured.

By removing https://github.com/styled-components/babel-plugin-styled-components/blob/950692b92855f17609e4281d5081e3d2acbf4b6b/src/utils/detectors.js#L24 the displayname will be rendered again.

aurerua commented 3 years ago

I couldn't find a working solution either. In order to ease debugging until a solution emerges, I use the .attrs constructor like this:

const Content = styled.div.attrs({ 'data-testid': 'Content' })`
  margin-top: 21px;
`
mgodwin commented 3 years ago

We were struggling with this as well. For us, I noticed the same thing as @baybara-pavel, that when we used import styled from 'styled-components' rather than import styled from 'src/styledComponents' the debug names appeared correctly in the DOM. We use typescript over here and originally defined a file that re-exported the constants from the original import for typing purposes. However, looking at the docs on the styled components site, it's actually not recommended or necessary to re-export everything from a src/styledComponents file anymore! https://styled-components.com/docs/api#styling-components

That's it! We're able to use styled-components just by using any original import. import styled, { createGlobalStyle, css } from 'styled-components';

// theme is now fully typed

This is a double-win IMO, since folks on our team would accidentally use the original import all the time. Now I can get rid of that, and I have a much better debugging experience (and still retain types!). 🎊

frisbee09 commented 3 years ago

Yes, I think best practice here changed and was updated in the docs. I too migrated to the new approach. There’s a reason why all three of us re-exported to use SC with typescript; it was in the docs before!

On 8 Jun 2021, at 21:47, Mark Godwin @.***> wrote:

ο»Ώ We were struggling with this as well. For us, I noticed the same thing as @baybara-pavel, that when we used import styled from 'styled-components' rather than import styled from 'src/styledComponents' the debug names appeared correctly in the DOM. We use typescript over here and originally defined a file that re-exported the constants from the original import for typing purposes. However, looking at the docs on the styled components site, it's actually not recommended or necessary to re-export everything from a src/styledComponents file anymore! https://styled-components.com/docs/api#styling-components

That's it! We're able to use styled-components just by using any original import. import styled, { createGlobalStyle, css } from 'styled-components';

// theme is now fully typed

This is a double-win IMO, since folks on our team would accidentally use the original import all the time. Now I can get rid of that, and I have a much better debugging experience (and still retain types!). 🎊

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

iDVB commented 2 years ago

We continue to have this issue with styles not being applied to the correct element. Have yet to find any solution other then to roll back to babel-plugin-styled-components@v1.10.3 in both our ui lib as well as all consuming projects.

Please help! No idea how to fix this and been limping along with 1.10.3 for months now.

hayzey commented 2 years ago

Using styled imported directly from styled-components instead of a re-exported module fixed it for us.

DanielCashlink commented 2 years ago

I never re-exported styled from anywhere, and this issue is still present with version 2.0.7

Nevermind, for me, I accidentally had babelrc: false in my webpack babel-loader config, so... user error, not an issue with this package