styled-components / xstyled

A utility-first CSS-in-JS framework built for React. 💅👩‍🎤⚡️
https://xstyled.dev
MIT License
2.28k stars 105 forks source link

Babel Macros - not working #44

Closed yairEO closed 3 years ago

yairEO commented 5 years ago

Hi, it would seem I cannot import the macro version of styled-components:

https://www.styled-components.com/docs/tooling#babel-macro

import styled from '@xstyled/styled-components/macro';

Failed to compile. Error: Cannot find module '@xstyled/styled-components/macro'

Thought trying also importing from @xstyled/macro but no luck.


Importing directly from styled-components does work well:

import styled from 'styled-components/macro';

Background:

We have an app based on create-react-app, not ejected, and not using rewire, because CRA supports babel macros, and I wish to utilize that ability to be able to use the babel-plugin-styled-components plugin.

I need this so my styled-components will be generated with a real display name, to be able to access components in enzyme unit tests.

Related thread

gregberge commented 5 years ago

Hello, yes it is not yet supported. If someone want to work on it, feel free. Else I will probably do it in september.

yairEO commented 5 years ago

I've implemented xstyled in dozens of files in a large app thinking I could use the Babel macro later (for testing) but was surprised it did not work.

Sadly, I do not have the time to look into this, because I am working full time, plus have my own Github open-source projects to maintain, with plenty of open issues to address

Enjoy your summer holiday! I highly appreciate your major contribution to the styled-component community.

jmlweb commented 5 years ago

@neoziro Shall I work on this?

gregberge commented 5 years ago

@jmlweb yes you can!

jmlweb commented 5 years ago

@neoziro My idea is to create Higher Order Functions over the current logic so that you can pass the utils from the styled-components version required (standalone or macro). Something like this:

export const buildCss = scCss => {
  return function css(...rawArgs) {
    const scCssArgs = scCss(...rawArgs)
    const flattenedArgs = flattenStrings(scCssArgs)
    return flattenedArgs.map(transform)
  }
}

and then, you use it like this:

import { css as scCss } from 'styled-components'
import { buildCss } from './_internal'

export const css = buildCss(scCss)

or

import { css as scCss } from 'styled-components/macro'
import { buildCss } from './_internal'

export const css = buildCss(scCss)

Does it looks good, or do you have a better implementation idea?

gregberge commented 5 years ago

It should work yes. No I don't have better idea.

jmlweb commented 5 years ago

It seems it is not that simple... It seems we need to export the enhanced version of the Styled Components macro, but I still had no luck. We'll try to learn a bit about macros before taking this task.

yairEO commented 5 years ago

Hi, anyone knows if there is active development on this?

jmlweb commented 5 years ago

I took a look, but I don't have any idea about how babel macros work, so I got no success... Feel free to take it :)

yairEO commented 5 years ago

@jmlweb - I know even less 😝

Are we stuck with nobody that knows and can help? Are we doomed refreshing this issue once a month to see no activity?

gregberge commented 5 years ago

I am afraid I am the only one involved who knows how to do it. Unfortunately it is not a required feature for me, so I can't give you a date for that feature.

Wizyma commented 5 years ago

Hey @neoziro I started to work on this issue today, but actually i think there is some issues between babel-plugin-macro and rollup. The umd version don't even build at all :D cf: most recent one : related issue oldest: oldest issues And it doesnt seem to be solved...

My work around on this was to remove the name from the rollup config of the package styled-components to build only the cjs and esm version. omg

And still there is some issues when files are builded instead of having the import as:

... = require('styled-components/macro')
// we have
... = require('styled-components')

so i used the plugin babel-plugin-transform-rename-import, but still when i test it with a yarn link it throw an error so i am like 🤯! the error is probably related to this issue

gregberge commented 5 years ago

@Wizyma you have to create a specific folder inside the styled-components folder with a package.json and create a specific rollup build for that. So the macro will not have umd. It is like a package inside another.

Wizyma commented 5 years ago

@neoziro yeah i thinked about that but i didnt knew how much liberty i could take to do what i need for that :D And then we should expose a @xstyled/styled-components/macro i think but still, it doesnt change this fact...

yairEO commented 4 years ago

Any progress in this? This is mega important because I cannot eject my React app and I need automatic classnames for my styled-components for Selenium E2E tests.. Thanks.. This package is deeply integrated in our app in hundred+ files..

weyert commented 4 years ago

Looks like the styled-components issue has been fixed in CRA: https://github.com/styled-components/styled-components/issues/2713#issuecomment-557802907

I would suggest roll your own babel macro if the problem persists.

gregberge commented 3 years ago

Still an issue for v2.

agriffis commented 3 years ago

I know that people would like the macro to work, but for reference in the meantime, here is the formula for using the plugin with xstyled and CRA

  1. Install rescripts (replacement for rewire) and the plugin

    yarn add -D @rescripts/cli @rescripts/rescript-env babel-plugin-styled-components
  2. Apply this change to package.json

    --- a/package.json
    +++ b/package.json
       "scripts": {
    -    "start": "react-scripts start",
    -    "build": "react-scripts build",
    -    "test": "react-scripts test",
    -    "eject": "react-scripts eject"
    +    "start": "rescripts start",
    +    "build": "rescripts build",
    +    "test": "rescripts test"
    +  },
    +  "rescripts": [
    +    "env"
    +  ],
    +  "babel": {
    +    "presets": [
    +      "react-app"
    +    ],
    +    "plugins": [
    +      [
    +        "babel-plugin-styled-components",
    +        {
    +          "topLevelImportPaths": [
    +            "@xstyled/styled-components",
    +            "@xstyled/styled-components/no-tags",
    +            "@xstyled/styled-components/native",
    +            "@xstyled/styled-components/primitives"
    +          ]
    +        }
    +      ]
    +    ]
       },
  3. If you don't already import React at the top of your components, you'll get a build error, so you'll need to add to each one:

    import React from 'react'

@gregberge It would be super cool if the classes generated by <x.div ...> also had classes for debugging, e.g. Filename__LineNo but I haven't looked at what would be involved for that. This kind of debuggability is the biggest concern that I hear from devs working on our projects internally.

gregberge commented 3 years ago

@agriffis it is not related to Babel Macro, but I agree with you! https://github.com/gregberge/xstyled/issues/190

agriffis commented 3 years ago

There are two things preventing the macro from working:

  1. It is hard-coded to 'styled-components', see https://github.com/styled-components/styled-components/blob/master/packages/styled-components/src/macro/index.js#L18-L21

  2. The macro bundles an older version of the plugin, before topLevelImportPaths was supported. Even if you have the newer version installed, or if you use "resolutions" to try to force it, it won't work. The upstream repo needs to be rebuilt and released with the updated plugin.

Anyway, all of this needs to become an issue and PR upstream. I'll work on that soon

agriffis commented 3 years ago

Pull request is in! Unfortunately it also looks like styled-components upstream is on hiatus, so it could take a while.

Also, the PR is against v6 in development, and then it would need to be backported to the legacy-v5 branch. I have a lot of uncertainty about how quickly this will move forward.

If you want to give it a thumbs up, head over to https://github.com/styled-components/styled-components/pull/3422

If you need something earlier, you can yarn add -D @scampersand/styled-components.macro and then add to your package.json

  "babelMacros": {
    "styledComponents": {
      "importModuleName": "@xstyled/styled-components"
    }
  },

then you can import styled from '@scampersand/styled-components.macro' and it should work.

agriffis commented 3 years ago

Quick update

This has been merged now to styled-components v6 in development, see https://github.com/styled-components/styled-components/pull/3422

I've also opened the PR to get it on v5 legacy, which is the current stable version, see https://github.com/styled-components/styled-components/pull/3432

That's progress, but unfortunately we're still between releases. There haven't been any v6 development releases, and the last v5 release was in October 2020, so it's hard to say when this will be available for general use. Feel free to give the v5 PR a thumbs-up, it might help.

In the meantime you can use @scampersand/styled-components.macro as mentioned above, it's effectively the same as what I put the in the PR for styled-components

agriffis commented 3 years ago

Great news, styled-components 5.2.2 was released with this fix :tada:

https://github.com/styled-components/styled-components/releases/tag/v5.2.2

I think all we need now is an update to xstyled docs and we can close this.