Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript responsive variants missing custom screens on Vercel #189

Open
troymcginnis opened this issue Apr 30, 2024 · 8 comments
Open
Labels
bug Something isn't working

Comments

@troymcginnis
Copy link

troymcginnis commented Apr 30, 2024

Describe the bug
When developing locally, the types for responsiveVariants appears to pick up all of our custom screens from our tailwind.config.js. This means we're able to see, get autocomplete for, and build components using our custom screens such as xs and 3xl using tv(). However, if we're referencing any of these custom screens, our builds are breaking on Vercel stating:

Type error: Object literal may only specify known properties, and 'xs' does not exist in type '{ sm?: "horizontal" | "vertical"; md?: "horizontal" | "vertical"; lg?: "horizontal" | "vertical"; xl?: "horizontal" | "vertical"; "2xl"?: "horizontal" | "vertical"; initial?: "horizontal" | "vertical"; }'.

It looks like the default Tailwind screens are being generated rather than the custom screens—though only on Vercel (works locally but we haven't tested this anywhere else other than locally and Vercel).

My assumption is that this has something to do with our generated.d.ts file for TVGeneratedScreens. I'm unsure how to proceed without doing something hacky in TS to get our builds to succeed on Vercel or if I'm just doing something inappropriate.

This is our tailwind.config.ts setup:

// ./src/design/theme/tokens/screens.ts
export const screens = {
  xs: '340px',
  'archive-mobile': '450px',
  'team-mobile': '450px',
  'navigation-mobile': '500px',
  sm: '640px',
  md: '900px',
  'navigation-desktop': '1000px',
  lg: '1200px',
  xl: '1600px',
  '2xl': '2000px',
  '3xl': '2400px',
  '560': '560px',
  '750': '750px',
}
// tailwind.config.ts
import type { Config } from 'tailwindcss'
// ..
import screens from './src/design/theme/tokens/screens'

export default withTV({
  content: ['./src/**/*.{js,ts,jsx,tsx}'],
  plugins: [
    // ...
  ],
  theme: {
    screens
    // ...
  },
}) satisfies Config

And the component raising the TS error on Vercel:

const filterList = tv(
  {
    base: 'mt-2 flex items-start gap-2',
    variants: {
      layout: {
        horizontal:
          'flex-row mb-2 box-[mx*-1] box-px overflow-y-hidden overflow-x-scroll [-ms-overflow-style:none] scrollbar-width-none [&::-webkit-scrollbar]:hidden',
        vertical: 'flex-col',
      },
    },
  },
  { responsiveVariants: true }
)

// ...

<div
  className={filterList({
    layout: { initial: 'horizontal', xs: 'vertical' },
  })}
>

Note that we can see all of the correct screens here:
Screenshot 2024-04-30 at 3 08 55 PM

Vercel error:

Type error: Object literal may only specify known properties, and 'xs' does not exist in type '{ sm?: "horizontal" | "vertical"; md?: "horizontal" | "vertical"; lg?: "horizontal" | "vertical"; xl?: "horizontal" | "vertical"; "2xl"?: "horizontal" | "vertical"; initial?: "horizontal" | "vertical"; }'.

To Reproduce
Steps to reproduce the behavior:

  1. Override the default screens in your tailwind.config.ts
  2. Use tv  local config to set responsiveVariants to true
  3. Set a non-standard screen size in your responsive variant
  4. Deploy project to Vercel
  5. Note the error in the build log

Note: If I use a standard screen size (ie. 'sm' | 'md' | 'lg' | 'xl' | '2xl', there's no error)

Expected behavior
No build error and everything works as expected as it does locally.

Screenshots
Screenshot 2024-04-30 at 3 15 49 PM

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: Chrome
  • Version: Version 123.0.6312.86 (Official Build) (arm64)

Additional context

  • Vercel CLI 33.7.1
  • Node v20.11.0
@troymcginnis troymcginnis added the bug Something isn't working label Apr 30, 2024
@troymcginnis
Copy link
Author

troymcginnis commented May 1, 2024

As an update, we're currently using a hacky workaround that seems to be appeasing the issue both locally and on Vercel.

// types.ts
export type ResponsiveScreens = keyof typeof screens
import { ResponsiveScreens } from '@types'

// ...

const filterList = tv(
  {
    base: 'mt-2 flex items-start gap-2',
    variants: {
      layout: {
        horizontal:
          'flex-row mb-2 box-[mx*-1] box-px overflow-y-hidden overflow-x-scroll [-ms-overflow-style:none] scrollbar-width-none [&::-webkit-scrollbar]:hidden',
        vertical: 'flex-col',
      },
    },
  },
  { responsiveVariants: true as unknown as ResponsiveScreens[] }
)
Screenshot 2024-05-01 at 10 33 35 AM

The solution is a bit cumbersome to implement and doesn't feel great since we're casting a boolean  to an array of screen sizes. On the flip side, we're getting accurate types and autocomplete across the codebase and we're no longer seeing the error on Vercel.


However, we're now seeing a new error in the Vercel logs, though it doesn't stop the build.

Tailwind Variants Transform Failed: Unexpected identifier

Screenshot 2024-05-01 at 10 36 09 AM

Checking the frontend, our responsive variants are working as expected, including non-standard screens, so I'm not sure what the deal is.

@troymcginnis
Copy link
Author

troymcginnis commented May 1, 2024

Looks like I've spoken too soon. Another one of our projects is seeing an error causing a build failure.

Screenshot 2024-05-01 at 11 07 34 AM

My TypeScript knowledge is a bit limited but I wonder if there's a way to have allow screen sizes, if custom to be statically typed? Or perhaps there's some further insight?

@troymcginnis
Copy link
Author

Another update:

I've found a reliable workaround that feels better than previous attempts, though not great.

Further information:

It looks like it's somehow related to how Vercel caches node_modules. On a new branch cut, creating a new preview branch on Vercel, all of the TVGeneratedScreens are showing the correct, custom values. If screens are added/removed/updated, these changes are not picked up. If a deployment is made without cache (ie. by deselecting "Use existing Build Cache" in the dashboard) all of the custom screens generated during the initial branch cut are wiped out and only the default Tailwind screens ('sm' | 'md' | 'lg' | 'xl' | '2xl') remain.

Current Workaround:

Our current workaround involves forcefully generating the TVGeneratedScreen type on each deployment with the following:

// generate-tv-types.ts
import { generateTypes } from 'tailwind-variants/dist/generator.js'
import { screens } from './src/design/tokens/screens'

generateTypes({ screens })
// package.json
{
  // ...
  "scripts": {
    "dev": "next",
    "build": "yarn build:web",
    "build:web": "yarn build:tv && yarn build:favicon && next build && yarn build:sitemap",
    "build:tv": "tsx ./generate-tv-types.ts",
    // ...
  },
  // ...
  "devDependencies": {
    "tsx": "^4.8.2"
    // ...
  }
}

Could be worse 🤷🏼

I'm not really sure how to further address the issue as I would expect the generateTypes() call from within the withTV() method to work fine on build since we build TW CSS on deploy as well which, I would expect, would include tailwind.config.ts, thus withTV(), thus generateTypes()  would fire—alas, I'm missing something in my understanding to further diagnose the issue.

Happy for any further insight. Also happy to roll this into our base and move forward with it if there's no further insights at this time.

@troymcginnis
Copy link
Author

Update:

I've opened a support ticket with Vercel to investigate on their end as well. In the meanwhile, if there's interest in troubleshooting further, I've setup a pubic minimal reproducible repository which can be cloned/forked and deployed to Vercel to immediately see the error: https://github.com/gearbox-built/tailwind-variants-vercel

Screenshot 2024-05-02 at 4 35 34 PM

@troymcginnis
Copy link
Author

Update:

Vercel suggests that it's solely the responsibility of the package and falls out of their scope of support. I am not familiar enough with tailwind's JIT compiler, how it relates to the tailwind.config.js and how this all, ultimately, effects the withTV function.

Can anyone (@mskelton?) lend some understanding around how the withTV function ties into a build process to help narrow down if this is a tailwind-variants thing or a Vercel this?

@mskelton
Copy link
Collaborator

@troymcginnis I don't use withTV in any of my projects at work, so I'd honestly have to lean more on @jrgarciadev in regards to his experience with responsive variants and the transformer.

@jrgarciadev
Copy link
Member

@tianenpang

@Code-Victor
Copy link

@troymcginnis I don't have any idea of how to fix your issue, but your documentation is top notch!!!
It should make it easier for @tianenpang to help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants