TypeScript responsive variants missing custom screens on Vercel
troymcginnis opened this issue · 12 comments
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:
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:
- Override the default
screens
in yourtailwind.config.ts
- Use
tv
local config to setresponsiveVariants
totrue
- Set a non-standard screen size in your responsive variant
- Deploy project to Vercel
- 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.
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
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[] }
)
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
Checking the frontend, our responsive variants are working as expected, including non-standard screens, so I'm not sure what the deal is.
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.
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
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?
@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.
@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
Hi @troymcginnis, could you please provide a repository to reproduce the issue or please share the versions of next
, tailwind-variants
, tailwindcss
, and typescript
you're using in your project. thanks!
The generateTypes
method will be triggered every time tailwind.config
is changed and executed before linting and checking the validity of types
in the Next App. At this point, the types for screens
should already be synchronized with the custom settings 🤔
I can't reproduce this issue here https://github.com/tianenpang/nextui-demo
The build logs
Hi troymcginnis, could you please provide a repository to reproduce the issue or please share the versions of
next
,tailwind-variants
,tailwindcss
, andtypescript
you're using in your project. thanks!
@tianenpang Repository to reproduce available here: https://github.com/gearbox-built/tailwind-variants-vercel.