vercel / turborepo

Build system optimized for JavaScript and TypeScript, written in Rust
https://turbo.build/repo
MIT License
26.48k stars 1.84k forks source link

[turborepo] Examples are too simple: missing a real-world example with tree-shakeable, RSC-ready library #6019

Closed raphaelbadia closed 11 months ago

raphaelbadia commented 1 year ago

Which project is this feature idea for?

Turborepo

Describe the feature you'd like to request

Hello,

I've skimmed through the turborepo examples and I haven't yet been able to get together a working example that could:

Describe the solution you'd like

I'd like a kitchen-sink like example but more in-depth: its Link and CounterButton are currently client components due to the banner in the tsup.config.ts, but they could totally be server components.

It would be great if it could support shadcn which is gaining much popularity now. It's also a great idea because shadcn/ui brings in a bit of complexity by installing third party packages. That would make it more "real", at least to me. Because with barrel exports, I've always struggled with bundle size!

Describe alternatives you've considered

I've considered doing it myself but I couldn't make it.

So far I've been able to "fix" the "go-to definition problem" starting from the with-tailwind example, but couldn't do anything about the tree shaking.

I've tried many things from different github issues to support the "use client" at the file-level instead of the package-level, but I wasn't able to make it work. Even tried to create a with-tailwind package using rollup instead of tsup. I failed

Thanks!

UlasCanAk commented 1 year ago

Fully agreed, this has been very frustrating for me as well. It's unclear to me how I can get a proper setup with all the requirements you listed working with 2 Next apps and a shared ui library. Have you been able to find a solution or workaround yet? How did you fix the go-to definition problem? Also, have you been able to put components in subdirectories inside the src folder of the ui package? Doing that did not work for me, even when changing the tsup config.

yasssuz commented 1 year ago

We need this

raphaelbadia commented 1 year ago

We indeed need this.

Currently my apps are using transpilePackages and imports are like this to work around the tree-shaking issue:

import FormInput from '@acme/ui/src/forms/FormInput';
import Button from '@acme/ui/src/ui/Button';

Building our packages instead of transpiling would allow us to fasten the build time, as packages would be cached between build. Currently the build process with rebuild all monorepo packages used by my app.

I'd just love to do

import { Button, FormInput } from '@acme/ui';

As seen in the turborepo examples, but it's not real-world compatible...

bel7aG commented 1 year ago

Same here, tried multiple ways but no result, even with nextjs modularizeImports and the experimental optimizePackageImports

mehulkar commented 1 year ago

Thanks for the request! I'll take it to the team to see if we'd be able to create and maintain such an example!

Neosoulink commented 1 year ago

@mehulkar, I'm interested in this issue, Is someone or a team working on it?

I'll be glad to contribute to this one.

mehulkar commented 1 year ago

@Neosoulink @anthonyshew is owning this, you may be able to collaborate

Neosoulink commented 1 year ago

Hey @anthonyshew, is this issue in the planning?

yasssuz commented 12 months ago

@anthonyshew @mehulkar How can I collaborate?

anthonyshew commented 12 months ago

@Neosoulink @yasssuz Head on over to #6682!

raphaelbadia commented 12 months ago

@anthonyshew Hello, thanks for taking the time to address this issue, however the basic example you updated sounds more like a workaround 😔

The basic example uses transpilePackages, which technically works but doesn't build at package level so it doesn't leverage full turborepo caching (see https://github.com/vercel/turbo/issues/6019#issuecomment-1764683135 ) If I have 5 apps (I do at my job), we end up transpiling and recompiling all of our 10 packages for each project.

I also think that the treeshaking suggested is not realistic :

CleanShot 2023-12-04 at 10 52 45@2x

Doing that is going to be hard to maintain IMO !

anthonyshew commented 12 months ago

Compiling a package before the Next.js Compiler bundles it won't result in faster build times. The Next.js Compiler still must parse the third-party code to create bundles. Achieving better granularity is one of the reasons Turbopack is being built.

The tree-shaking shown is realistic. We use this technique in our monorepo at Vercel. If you'd prefer, you can use

"exports": {
  "./*: "./src/*"
}

but you'll lose auto-importing across package boundaries.

vimtor commented 11 months ago

Compiling a package before the Next.js Compiler bundles it won't result in faster build times. The Next.js Compiler still must parse the third-party code to create bundles. Achieving better granularity is one of the reasons Turbopack is being built.

The tree-shaking shown is realistic. We use this technique in our monorepo at Vercel. If you'd prefer, you can use

"exports": {
  "./*: "./src/*"
}

but you'll lose auto-importing across package boundaries.

Sorry for the aside, but would compiling the package speed up TypeScript type inference since it can rely on declaration files?

robknight commented 11 months ago

redirect to the appropriate file when doing a cmd+click: currently in the examples, "go to definition" will bring you to a .d.ts. That's not what devs expect when developing in a monorepo.

I've encountered this issue, and so far as I can tell this is because tsup doesn't generate declaration maps. If you want declaration maps then rather than using tsup --dts, you have to use something like tsup <options> && tsc --emitDeclarationOnly --outDir=dist/types, with "declarationMap": true in your tsconfig.json.