stitchesjs / stitches

[Not Actively Maintained] CSS-in-JS with near-zero runtime, SSR, multi-variant support, and a best-in-class developer experience.
https://stitches.dev
MIT License
7.76k stars 254 forks source link

TypeScript issue when exporting `styled` from a monorepo package #1055

Open lucastobrazil opened 2 years ago

lucastobrazil commented 2 years ago

Bug report

Describe the bug

I have a monorepo setup (see below for minimal repro) with the following structure:

monorepo/
-- packages
--- core
--- system

system is where we're exporting styled from stitches, however when using it in core

import { styled } from '@org/system'

const MyComponent = styled('div', {});
       ^^^^^^^^^^^

the below TypeScript error occurs.

The inferred type of 'MyComponent' cannot be named without a reference to 'system/node_modules/@stitches/react/types/config'. This is likely not portable. A type annotation is necessary.

We managed to eliminate this error by removing declaration: true from the tsconfig of core, however this prevented declaration files from getting created for our components which killed TS autocompletion (a big DX reason for using stitches).

Prior to moving the stitches stuff to system, it was in he core directory and worked fine.

To Reproduce

https://github.com/lucastobrazil/stitches-ts-repro

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Clone the repo and open with VSCode (Typescript enabled)
  2. npm install <-- we're using 4.4.2 to stay in line with stitches
  3. cd packages/system && npm install <-- install within this package too
  4. navigate to packages/core/index.ts and you will see the typescript error below

Expected behavior

We'd expect that the typings of the styled function are accessible and no error occurs, whilst still being able to output declaration files from core

Screenshots

Screen Shot 2022-07-05 at 11 53 50 pm

System information

andresmarpz commented 2 years ago

I wanted to take a look at this but couldn't reproduce the error of that example. I followed the steps @lucastobrazil provided above.

Here is my fork. Once I noticed the error wasn't there I added this line to check that TypeScript was working as intended.

image

It might be something on my side so it would be great if someone else could take a look at it as well.


System information

lucastobrazil commented 2 years ago

@andresmarpz thanks for taking a look! try doing npm i in the system folder and the error should show up. Once stitches gets installed the TS error gets thrown. Not sure if this sheds any more light on the issue, but i guess once it's installed as a dependency TS tries to actually go in and infer the types.

lucastobrazil commented 2 years ago

ps ill add that instruction to the reproduction steps

andresmarpz commented 2 years ago

Yep, you were right. I could get the reproduction working and tried a few things but couldn't find a workaround. Though, I don't know if it's really a Stitches problem, since I found #42873 and #29808 in TypeScript repository and reading a little through them it seems those are very related to your issue. Hope that might point you into something useful, but I'm not that knowledged to help you here :/

jgoz commented 2 years ago

I just ran into this and resolved it by coercing npm to install @stitches/react in the root node_modules folder rather than in a workspace node_modules. I'm not sure why it wasn't being hoisted to the root since it's only a dependent of that one package, but it resolved the issue for me.

ivanbanov commented 2 years ago

I faced the same issue with a pnpm monorepo. It seems to be directly related to this issue https://github.com/microsoft/TypeScript/issues/48212 and seems like it won't go away until it's fixed.

I ended with 3 possible workarounds

Option 1: Set paths

In your root tsconfig add @stitches/react to the paths

// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      // TODO: Remove the workaround whenever MS fixes the issue
      // https://github.com/microsoft/TypeScript/issues/48212
      "@stitches/react": ["./node_modules/@stitches/react"]
    }
  }
}

Option 2: Set baseUrl

I didnt try with other package manager, for a pnpm monorepo using workspace:* for local dependencies it worked fine

{
  "compilerOptions": {
    // TODO: Remove the workaround whenever MS fixes the issue
    // https://github.com/microsoft/TypeScript/issues/48212
    "baseUrl": "./node_modules"
  }
}

Option 3: Add an empty type import

Based on this comment https://github.com/microsoft/TypeScript/issues/48212#issuecomment-1204325586, in your component file add the following import

// TODO: Remove the workaround whenever MS fixes the issue
// https://github.com/microsoft/TypeScript/issues/48212
import type {} from '@stitches/react'

I hope it helps somehow :)

Gorthog commented 2 years ago

@ivanbanov thank you so much! It worked! Can you please explain a bit more what is actually going on here? What is the root cause? Why these workarounds help?

gregogun commented 2 years ago

@ivanbanov for option 2, did you also put this in the root tsconfig.json? I'm still getting the same error with these solutions, so maybe I'm missing something. Do you have stitches installed at the root package.json too?

drianoaz commented 2 years ago

I solved this problem installing the @stitches/react as dependency of the package that was having typing problems

gregogun commented 2 years ago

I solved this problem installing the @stitches/react as dependency of the package that was having typing problems

hmm tried this but still found some issues... are you able to share the repo at all? @drianoaz πŸ™

ivanbanov commented 2 years ago

@gregogun I only have a tsconfig.json in the root

@Gorthog if I understood this comment correctly, TS resolves the transitive dependencies as "out of the project" and can not simply import it (I dont understand deeply to be honest). So, based on this transitive problem what I tried was to give a happy path to the compiler, so it does not get lost with such deps. Option 2 seems dangerous to be honest, but anyway it works 🀷

drianoaz commented 2 years ago

hmm tried this but still found some issues... are you able to share the repo at all? @drianoaz πŸ™

@gregogun the project where I made this fixes is private, but if you tell me which error exactly you are having, maybe I can help you

gregogun commented 2 years ago

thanks for the response @ivanbanov @drianoaz

manage to solve the issue with @ivanbanov second solution, turns out I had a missing ts dependency in my theme package.

it is working fine but I've noticed by doing this I lose the typed HTML attributes onClick, disabled etc. . Does anyone know a way to fix this? It will ofc work by extending React.ComponentProps<html element in here> but would really prefer not to do this πŸ˜…

Gorthog commented 1 year ago

@gregogun I only have a tsconfig.json in the root

@Gorthog if I understood this comment correctly, TS resolves the transitive dependencies as "out of the project" and can not simply import it (I dont understand deeply to be honest). So, based on this transitive problem what I tried was to give a happy path to the compiler, so it does not get lost with such deps. Option 2 seems dangerous to be honest, but anyway it works 🀷

Thanks for that explanation!

I would like to add my 2 cents:

In my case I've found the problem is due to pnpm creating multiple copies of the same npm package across the monorepo. I changed all references of said package to peerDependencies except one that stayed under dependencies. Once that was done, there was only once copy of the npm package under node_modules and the error went away.

jpedroschmitz commented 1 year ago

I faced this issue in a monorepo containing the Design System using Stitches and its applications. I tried @ivanbanov workarounds, but none worked for me (still unsure why). Instead of trying a workaround or manually using type annotation on every usage of the styled function, I took a different approach. Here's how I fixed it:

  1. Install @stitches/react in both the design system package and the application.
  2. Create a shared Stitches configuration file in your design system package called stitches.shared.ts:
    
    // stitches.shared.ts
    import { createStitches } from '@stitches/react';
    // Import your theme configuration here
    import { themeConfig } from './path/to/your/themeConfig';

export const stitches = createStitches(themeConfig);

export const { styled, css, config, getCssText, globalCss, keyframes, } = stitches;


Remember that you'll have to export this file, so update the bundling library you're using to have this file as an entry.

3. Update the `stitches.config.ts` (or however you call it) file in your design system package to import and re-export the shared configuration:
```ts
import { stitches, styled, css, config, getCssText, globalCss, keyframes } from './stitches.shared';

export { styled, css, config, getCssText, globalCss, keyframes };

export type CSS = StitchesCSS<typeof config>;
  1. Create a stitches.config.ts file in your application:
    
    import { StitchesCSS } from '@stitches/react';
    import { stitches, styled, css, config, getCssText, globalCss, keyframes } from 'path/to/design-system-package/stitches.shared';

export { styled, css, config, getCssText, globalCss, keyframes };

export type CSS = StitchesCSS;



This configuration file imports the shared Stitches configuration from the design system package and re-exports it for use in the application. By doing this, we ensure the design system package and the Next.js application use the same Stitches configuration, fixing the type-related issues. This alternative solution should help resolve the error without using a workaround. πŸ™ŒπŸ» 
JackMostert commented 1 year ago

Hope this will help, following the steps above from everyone, I still wasn't able to stop the error from showing; So I started to play around with the tsconfig.json and found that setting the moduleResolution to something other then "bundler" solved my issue;

{
  "compilerOptions": {
    "moduleResolution": "node16",
  }
}
OnkelTem commented 11 months ago

I faced this issue in a dead simple library and it doesn't seem like any of the solutions mentioned here are helping. It looks like a Stitches issue for me now. Let me try to reproduce the problem in a repository.

OnkelTem commented 11 months ago

Here you are: https://github.com/OnkelTem/_stitches-inferred

import { styled } from '@stitches/react';

export const Button = styled('button', {
    backgroundColor: 'gainsboro',
    borderRadius: '9999px',
    fontSize: '13px',
    padding: '10px 15px',
    '&:hover': {
        backgroundColor: 'lightgray',
    },
});

TS Error:

TS2742: The inferred type of Button cannot be named without a reference to
../node_modules/@stitches/react/types/css-util
. This is likely not portable. A type annotation is necessary.
OnkelTem commented 11 months ago

Opened a new report since it happens not only in a monorepo: https://github.com/stitchesjs/stitches/issues/1160

yovanoc commented 7 months ago

It would be cool to at least update the tsconfig of this repo...