twin.macro: ReferenceError: styled is not defined

In an otherwise well-working project with gatsby + styled-components (using tw prop, css prop, and tw import is working fine), I randomly can’t get the styled import to work and get ReferenceError: styled is not defined if I try.

The error doesn’t come up always. First I’ve managed to get it to work somehow. After that, I could get it to fail again with above error by:

  • randomly creating a reference error in an unrelated file (and getting the correct error message).
  • afterwards correcting the reference error
  • now the “ReferenceError: styled is not defined” crops up again.
  • the issue is not fixed by deleting the gatsby cache and building again.
  • it’s fixed by replacing the styled import from twin.macro by the one from ‘styled-components’
  • it’s not fixed by clearing/re-installing all node_modules.

Sorry I can’t pin it down more precisely.

The setup: gatsby 2.26.1, styled-components 5.2.1, twin.macro 1.12.1. (But playing with some earlier twin version didn’t appear to change the behaviour). Running in a yarn workspaces setting if that matters.

package.json:

  "babelMacros": {
    "twin": {
      "preset": "styled-components",
      "config": "src/tailwind.config.js",
      "autoCssProp": true,
      "debugProp": true,
      "debugPlugins": false,
      "debug": false
    }
  },

I’ve tried replacing the preset with

      "styled": {
        "import": "default",
        "from": "styled-components"
      },
      "css": {
        "import": "css",
        "from": "styled-components/macro"
      },
      "global": {
        "import": "createGlobalStyle",
        "from": "styled-components"
      }

but that didn’t change the outcome.

Btw: I love the twin project, your pace of adding new goodies is addictive…

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 24 (12 by maintainers)

Most upvoted comments

@ben-rogerson The problem still occurs in a quite peculiar case when the styled import is used together with this syntax:

const Component = tw['p']`text-base`

Take a look on this React component:

import { ElementType, PropsWithChildren, ComponentPropsWithoutRef, ReactElement } from 'react'
import tw, { styled } from 'twin.macro'

const Container = styled.div(() => [
  // some tyles here
])

export type TextProps<T extends ElementType> = PropsWithChildren<{
  as?: T
}>

export default function Text<T extends ElementType = 'p'>({
  as,
  children,
  ...rest
}: TextProps<T> & Omit<ComponentPropsWithoutRef<T>, keyof TextProps<T>>): ReactElement {
  // WARNING!: This is the problematic syntax:
  const Component = tw[(as || 'p') as string]`text-base`

  return <Component {...rest}>{children}</Component>
}

The returned error visible below:

image

points to the problematic line from the component source code above:

const Component = tw[(as || 'p') as string]`text-base`

However this syntax is processed correctly and runs without errors:

const Component = tw.p`text-base`

Dependencies:

  • react v17.0.2,
  • twin.macro v2.8.2,
  • @emotion/babel-plugin v11.7.2,
  • vite v2.7.13.

A workaround I came up with for this problem is to manually save lost reference to the styled import in the local variable called styledRef and create a styled element using that variable:

import { ElementType, PropsWithChildren, ComponentPropsWithoutRef, ReactElement } from 'react'
import tw, { styled } from 'twin.macro'

// Reference is preserved in the local variable during bundle processing:
const styledRef = styled

const Container = styledRef.div(() => [
  // some tyles here
])

// ...
// rest of the component code remains unchanged

I hope that my solution help to find the root cause and unblock the community while waiting for the fix.

@ben-rogerson I appreciate all the work you have done to create this macro. Thank you! 👍

Twin doesn’t have an item called format in it’s config. Try this config and see if it still fixes your issue @najathi:

"babelMacros": {
    "twin": {
      "preset": "styled-components",
    }
  }

yeah, it works @ben-rogerson. Thanks

Hi @ben-rogerson - my bad, I naively copied the button.tsx without reading the docs about the ts config. works! @types/react was already installed. moving on with tw now, wohoo! 👍 : Thanks a lot for the quick answer.