dai-shi/waku

ssr build / bundling wrong export from packages.json

aheissenberger opened this issue · 14 comments

Example:

  1. add react-textarea-autosize to package.json - this is a package optimized for react ssr with 2.5 Mio downloads and 1.279 dependents!
  2. add this component to a page
'use client';
import TextareaAutosize from 'react-textarea-autosize';

export const MyTextarea = () => {
    return (<div><TextareaAutosize/></div>);
}
  1. run pnpm waku build --with-ssr

Error: ReferenceError: document is not defined

The reason is that Waku bundles the wrong module node_modules/react-textarea-autosize/dist/react-textarea-autosize.browser.esm.js into rsc2-fcfef706c.js which is optimized for the browser and fails in nodejs when accessing the global document.

The correct file would be node_modules/react-textarea-autosize/dist/react-textarea-autosize.esm.js based on the "exports" section if the package.json.

Output:

vite v5.0.12 building SSR bundle for production...
✓ 43 modules transformed.
✓ built in 323ms
vite v5.0.12 building SSR bundle for production...
✓ 38 modules transformed.
dist/assets/entries-PGWLNLqW.css             0.17 kB
dist/assets/rsc1-8e67dcaea.js                0.27 kB
dist/assets/rsc2-fcfef706c.js                0.49 kB
dist/assets/rsc3-556e27fa2.js                0.69 kB
dist/assets/com0-28170e60f.js                1.26 kB
dist/assets/rsc0-47a606723.js                1.61 kB
dist/assets/waku-client.js                   2.64 kB
dist/assets/react.react-server-yjb63mRX.js   9.89 kB
dist/entries.js                             13.20 kB
dist/rsdw-server.js                         40.93 kB
✓ built in 111ms
vite v5.0.12 building for production...
✓ 63 modules transformed.
dist/public/index.html                        1.08 kB │ gzip:  0.46 kB
dist/public/assets/react.js                   0.06 kB │ gzip:  0.08 kB
dist/public/assets/com0-28170e60f.js          0.10 kB │ gzip:  0.10 kB
dist/public/assets/rsc3-556e27fa2.js          0.27 kB │ gzip:  0.20 kB
dist/public/assets/rsc1-8e67dcaea.js          0.29 kB │ gzip:  0.19 kB
dist/public/assets/main-Dn1pTRZ5.js           0.59 kB │ gzip:  0.37 kB
dist/public/assets/jsx-runtime--3Vb6qXs.js    0.69 kB │ gzip:  0.45 kB
dist/public/assets/indexHtml-sM_D3mTj.js      0.88 kB │ gzip:  0.50 kB
dist/public/assets/rsc2-fcfef706c.js          3.39 kB │ gzip:  1.57 kB
dist/public/assets/rsc0-47a606723.js          3.67 kB │ gzip:  1.62 kB
dist/public/assets/index-ZTOZCyuL.js          6.91 kB │ gzip:  2.68 kB
dist/public/assets/rsdw-client.js            13.20 kB │ gzip:  4.92 kB
dist/public/assets/waku-client.js            13.23 kB │ gzip:  5.06 kB
dist/public/assets/rd-server.js             162.42 kB │ gzip: 48.70 kB
dist/public/assets/index-ygKPTG2k.js        177.23 kB │ gzip: 55.26 kB
✓ built in 518ms
ReferenceError: document is not defined
    at file:///TST/waku-broken/dist/public/assets/rsc2-fcfef706c.js:1:1886
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^

ReferenceError: document is not defined
    at file:///TST/waku-broken/dist/public/assets/rsc2-fcfef706c.js:1:1886
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)

Node.js v21.6.1

Status:

  • pnpm waku dev --with-ssr - no Errors or Problems with the resulting website
  • pnpm waku build && pnpm waku start - no Errors or Problems with the resulting website

Previous discussion: #421 (comment)

Current status: I don't think there's a good way to solve it as of now. So, we would like to look for a workaround.

So, can adding document mock in define in your vite.config.ts be a workaround for react-textarea-autosize specific case?

Does anyone have any other workaround ideas?

This is not a specific case - I have tried some other Libraries which are all optimized for RSC and work with NextJS. They provide alternative code for RSC and SSR in their package.json export definition. All of them fail because the current build pipeline will alway prefer the browser modules for SSR and RSC.

I did choose this component as an example as it is a really simple one.

can adding document mock in define in your vite.config.ts be a workaround

My bad. It's not about vite, but the runtime. So, it doesn't work.

They provide alternative code for RSC and SSR in their package.json export definition.

Yeah, all of them would fail. Can you list all libraries you tried in this PR description?

Let's tackle this after v0.20.0. I really wish Vite will support two and more module graphs. (Another issue is that the "build" in Waku is quite slow.)

vitejs/vite#12715

I wonder if #90 is related, because it's close to Next.js.

This is not a specific case

I know this is not a specific case.
I just thought if there's an intermediate workaround that users can do in the mean time.

Let's tackle this after v0.20.0. I really wish Vite will support two and more module graphs.

On second thought, Vite won't be supporting it anytime soon. So, let's target this for v0.19.3.

#421 (comment) I just realized it again that this is PRD only issue, as the PR titles says.

I'm curious why DEV works without the error. 🤔
(edit) Okay, I get it. Vite on the worker thread is for RSC (incl. entries.tsx) and, Vite on the main thread is for SSR and clients.

maybe the new experimental Vite 5.1 beta Runtime API can help

Looks promising. Also for #113.

Okay, I think it's going to be a fairly easy fix for now. Will work on it.

@aheissenberger Can you try #457 and see if it works as expected?

@dai-shi 👏 - great work 💯