nitro icon indicating copy to clipboard operation
nitro copied to clipboard

`nitro/vite` will break down unocss in `tanstack start RC`

Open zouhangwithsweet opened this issue 3 months ago • 14 comments

Environment

  • nitro: 3.0.0-20250925-181710-5191890e
  • nodejs: v24.5.0

Reproduction

https://github.com/fisand/f3-app/tree/main/apps/web-tanstack

Describe the bug

If I use nitro/vite to build a tanstack start(RC) APP, it looks like will remove vite:css-post plugin, then the CSS will not generator succefully.

[plugin unocss:global:build:generate] [unocss] failed to find vite:css-post plugin. It might be an internal bug of UnoCSS

Other issue is nitro/vite will not match a 404 route to noFoundComponent in a tanstack start(RC) APP, it will always loading util the APP crash.

node:internal/deps/undici/undici:13484
      Error.captureStackTrace(err);
            ^

TypeError: fetch failed
    at node:internal/deps/undici/undici:13484:13

  [cause]: HeadersTimeoutError: Headers Timeout Error
      at FastTimer.onParserTimeout [as _onTimeout] (/node_modules/.pnpm/[email protected]/node_modules/undici/lib/dispatcher/client-h1.js:757:28)
      at Timeout.onTick [as _onTimeout] (/Users/SYY/Desktop/work/f3-app/node_modules/.pnpm/[email protected]/node_modules/undici/lib/util/timers.js:162:13)
      at listOnTimeout (node:internal/timers:594:17)
      at process.processTimers (node:internal/timers:529:7) {
    code: 'UND_ERR_HEADERS_TIMEOUT'
  }

Additional context

No response

Logs


zouhangwithsweet avatar Sep 28 '25 01:09 zouhangwithsweet

Can you please share a minimal reproduction with nitro plugin only + unocss? (no tanstack start)

pi0 avatar Sep 28 '25 12:09 pi0

Sorry I cannot make a reproduction successfully. But I think it has a relation with these codes:

https://github.com/unocss/unocss/blob/main/packages-integrations/vite/src/modes/global/build.ts#L127

async configResolved(config) {
        const distDirs = [
          resolve(config.root, config.build.outDir),
        ]

        // for Vite lib more with rollupOptions.output, #2231
        if (config.build.rollupOptions.output) {
          const outputOptions = config.build.rollupOptions.output
          const outputDirs = Array.isArray(outputOptions)
            ? outputOptions.map(option => option.dir).filter(Boolean) as string[]
            : outputOptions.dir
              ? [outputOptions.dir]
              : []

          outputDirs.forEach((dir) => {
            distDirs.push(dir)

            if (!isAbsolute(dir))
              distDirs.push(resolve(config.root, dir))
          })
        }

        const cssPostPlugin = config.plugins.find(i => i.name === 'vite:css-post') as Plugin | undefined
        const cssPlugin = config.plugins.find(i => i.name === 'vite:css') as Plugin | undefined

        if (cssPostPlugin)
          distDirs.forEach(dir => cssPostPlugins.set(dir, cssPostPlugin))

        if (cssPlugin)
          distDirs.forEach(dir => cssPlugins.set(dir, cssPlugin))

        await ready
      },

nitro/vite use a custom viteserver to build file, but the unocss just read the user's vite.config. So when it scan the file, it will not find the right path.

https://github.com/nitrojs/nitro/blob/main/src/build/vite/build.ts#L10

const builder = await createBuilder({
    base: nitro.options.rootDir,
    plugins: [nitroPlugin({ _nitro: nitro })],
  });

zouhangwithsweet avatar Oct 09 '25 02:10 zouhangwithsweet

So to fix it issue the easy way is that we can let unocss/vite know nitro output path. Just add the build.outdir filed. But I will not effect the nitro.

Image

zouhangwithsweet avatar Oct 09 '25 02:10 zouhangwithsweet

But I think it's a problem about nitro working with all other vite plugins. When we use nitro/vite, the development servert & the builder is not using a same config. What do you think about that ? @pi0

zouhangwithsweet avatar Oct 09 '25 02:10 zouhangwithsweet

Maybe we default userConfig.build.outDir when not set by users?

pi0 avatar Oct 09 '25 07:10 pi0

We can explicitly point out the differences in configuration between nitro/vite and other Vite plugins in the document to help users understand. Currently, considering that this will not affect the core functions of nitro, it is recommended that no changes be made for the time being.

zouhangwithsweet avatar Oct 10 '25 03:10 zouhangwithsweet

I also notice that nitro/vite have differrent behavoir with vite or rolldown/vite

zouhangwithsweet avatar Oct 10 '25 07:10 zouhangwithsweet

I also notice that nitro/vite have differrent behavoir with vite or rolldown/vite

nitro/vite hadn't supported rolldown-vite yet

gxres042 avatar Oct 10 '25 14:10 gxres042

[email protected] will break dev server down with tanstack start.

node:internal/url:826
      href = bindingUrl.parse(input, base, true);
                        ^

TypeError: Invalid URL
    at new URL (node:internal/url:826:25)

zouhangwithsweet avatar Nov 11 '25 08:11 zouhangwithsweet

I have added a fix to [email protected] to this issue. You can update lockfile to get fix.

(keeping issue open, we should fix some more places in nitro to avoid similar issues in the future)

pi0 avatar Nov 11 '25 20:11 pi0

nitro build will copy node_modules into server folder, but the packages's lost many files. Like drizzle-orm, it losts index.js balabla.

--- update --- I can fix it with the options noExternals: true, but nitro default value is false

zouhangwithsweet avatar Nov 12 '25 01:11 zouhangwithsweet

@zouhangwithsweet only used files will be traced. Did you get a runtime error for drizzle usage? (if yes it is a bug with nf3 integration)

pi0 avatar Nov 12 '25 09:11 pi0

@zouhangwithsweet only used files will be traced. Did you get a runtime error for drizzle usage? (if yes it is a bug with nf3 integration)

Yes, there is a runtime error.cannot resolve drizzel-orm/index.js. Look likes a upstream bug.

zouhangwithsweet avatar Nov 12 '25 09:11 zouhangwithsweet

I had updated https://github.com/fisand/f3-app/tree/main/apps/web-tanstack, you can reproduce it easily.

zouhangwithsweet avatar Nov 12 '25 09:11 zouhangwithsweet