-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Update tsup.config.ts to support "use client" of Next.js #6307
Update tsup.config.ts to support "use client" of Next.js #6307
Conversation
Right now the example works because nothing inside `ui` requires client-side rendering. `tsup` removes "use client" banners from files and breaks Client Components. Problem and fixes found at https://stackoverflow.com/questions/76525345/client-components-in-turborepo-cause-error
The latest updates on your projects. Learn more about Vercel for Git ↗︎
9 Ignored Deployments
|
🟢 Turbopack Benchmark CI successful 🟢Thanks |
🟢 CI successful 🟢Thanks |
I had written a couple of other comments, but ended up deleting them as I had missed the fact that once a component is marked with However, the options above still fail in a common scenario: In the Screenshots from the branch in this PR follow below, modified with the above import of a client component into a server component. First the Then the Below is the server component Turning Have you seen how the React team did it, by the way? They seem to build the folders separately: https://github.com/vercel/analytics/blob/main/packages/web/tsup.config.js |
@magnusriga nice catch on Server Components importing Client Components. I will update the scripts to walk through the client entry points and insert
Yes, I have tried that but it wouldn't work because Tailwind CSS requires reading both server and client components to create the stylesheet, so you will need to have a build with both server and client to create the style sheet. So you will end up with 3 builds: server only, client only, and server + client (for CSS)... which is something I am trying to avoid. |
@magnusriga added support for using Client Components inside Server Components within the same ( |
@williamli Awesome, that actually works. Two questions, if I may:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am approving this with a 'fixship'; I think a comment explaining the problem and motivation as well as why it doesn't work out of the box (either in the PR, or in the tsup.config.ts
itself) would go a long way to explain what is going on here.
@arlyon yeah, an update in README with details is in the work. I was waiting for @anthonyshew to come back to help on that but I can try to update it next week. |
@williamli Have you seen this, by Jared Palmer?: https://turbo.build/blog/you-might-not-need-typescript-project-references#nextjs Seems we might not need to build the internal packages at all. I.e. they can simply be imported from the src directory and next.js (or whichever framework one uses) can handle all the transpiling and bundling. The turbo docs suggest the same approach: https://turbo.build/repo/docs/handbook/sharing-code/internal-packages |
The larger answer here is that we don't want to bundle internal packages. Our examples today are indeed using Appreciate the work! |
@anthonyshew thank you for the input. Quick question: Can we just import the files from src and forget about the entire compilation and bundling step. I.e. just let Next.js handle all that, like the turbo docs explain in the internal packages section? If we do it that way, why do we need to compile anything with tsc? Can't we just let next.js (for instance) handle it all? It seems that's what the basic Next.js example you have in the docs show. Thanks a lot for the guidance. |
@magnusriga That is also an option - but it comes with a tradeoff. You won't be able to do as much caching since there aren't any outputs to cache on that internal package. Depending on the size of your repository, this could have a significant impact on your build times. EDIT: I was wrong about this. Can I blame Return from Parental Leave Brain? 😄 |
I finally figured out a setup that works in every way, including with Intellisense on the RHS paths of imports. The setup, and an example repo based on the basic turborepo starter, can be found here: microsoft/TypeScript#56412 (comment) |
Y'all, I'm incredibly sorry that I forgot we had this PR out. I'm coming back from parental leave and trying to get my head on straight still. While I was looking down the list of work I had out, I didn't realize that this PR was for the I worked on the
I'm going to favor #6575 for the sake of simplicity so if you'd like to leave critiques there, happy to have them! |
@anthonyshew thank you for that update. I see that you decided to not transpile the typescript in As a separate note, it would be nice not having to export each component manually. Meaning we could instead do this in the |
You can certainly let Additionally, with the approach we're using, we don't have to bring in a bundler at all (outside of the Next.js Compiler), reducing our repo's general overhead. Exporting |
Got it. One more question @anthonyshew , when you have time: I looked through your example, and see that you imported into See for instance here: https://stackoverflow.com/questions/74292749/tailwindcss-duplicate-css-classes-when-using-library-in-app (the OP ended up doing the cross-referencing you advised against). Side note: Can we fix the auto-import issue by using Thanks again! |
@anthonyshew In addition to my comment above, I think the README might be wrong. It says you are compiling the TS to dist. |
I tried this and this fails for me when I have client components imported in a server component. I think it's because the imports in the server component is from a chunk and the chunk does not have a "use client"; on top ( thought the client component file itself does ). |
@clearly-outsane check out the updated example (this was the PR that updated it) |
After digging into this, there seems to be
23 ways to do this:Option 1: Build first, use
onSuccess
hook to prepend use client to the start ofui/client
package entry points.Pro:
Con:
onSuccess
is completed, there is a brief moment where there is no ‘use client’ forui/client
, which might cause Next.js app to flash an error to complain about the missing ‘use client’… the error will go away onceonSuccess
is completed.Option 2: Use a separate config for
tsup
for a new/dist/use-client
file structure in whichuse client
is added as a js banner.Pro:
Con:
/client
are built twice. Note: I tried to skip/client
from being processed in the 2ndtsup
task, but doing that will isolate styles defined in/client
from tailwind’s stylesheet building task. classNames defined in/client
will not get included instyle.css
until files outside of/client
changes and trigger anothertsup
build.Option 3: Based on Option 1, we prepend
use client
in a staging area (/dist/server/client
) before moving the folder to/dist/client
. This addresses all the cons of option 1. An extra package (fs-extra) is required to handle the moving.