fastify / fastify-vite

Fastify plugin for Vite integration.
MIT License
859 stars 72 forks source link

Impossibel to build if you use anything other than Fastify vite. #158

Open AnzeKop opened 3 weeks ago

AnzeKop commented 3 weeks ago

Prerequisites

Fastify version

Latest

Plugin version

Latest

Node.js version

20

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

Sonoma

Description

I use a src/dist build approach and want my files to live in src/routes/client. It works fine in development and I can build it however needed but as the outDir is not configurable it fails when starting due to this if statement in production.js

` const clientDist = config.spa ? resolve(config.bundle.dir) : resolve(config.bundle.dir, 'client')

if (!exists(clientDist)) { throw new Error('No client distribution bundle found.') }

const serverDist = resolve(config.bundle.dir, 'server') if (!config.spa && !exists(serverDist)) { throw new Error('No server distribution bundle found.') }`

When I try setting the resolve to resolve(config.bundle.dir) for both the server and the client dist it passes this but then somehow finds a duplicate in the root path in the fastify static plugin

rootPath [ '/dist/client/assets', '/dist/client/assets' ]

Its extremly difficult to make this plugin work with anything else working along side it. Fastify autoload is also almost impossible to configure with Vite.

Link to code that reproduces the bug

No response

Expected Behavior

No response

onlywei commented 3 weeks ago

Can you share the relevant parts of your vite.config.js and the options that you're passing to FastifyVite in your server.js file?

AnzeKop commented 3 weeks ago

I've tried every possible config on the planet. This is what I have so far. Works locally, doesn't work in prod

import { join, dirname } from "path";
import { fileURLToPath } from "url";

import viteReact from "@vitejs/plugin-react";
import fastifyReact from "@fastify/react/plugin";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export default {
  root: join(__dirname, "src", "routes", "client"),
  build: {
    outDir: "../../../dist/client",
    emptyOutDir: true,
    ssrManifest: true,
  },
  plugins: [viteReact(), fastifyReact()],
  ssr: {
    external: ["use-sync-external-store"],
  },
};

Vite is registered in a seperate plugin file that is then consumed by Fastifys autoload

import fp from "fastify-plugin";
import { FastifyInstance } from "fastify";
import FastifyVite from "@fastify/vite";

import { join, dirname } from "path";
import { fileURLToPath } from "url";

const path = fileURLToPath(import.meta.url);
const __dirname = dirname(path);

export default fp(async (fastify: FastifyInstance, opts) => {
    await fastify.register(FastifyVite, {
      root: join(__dirname, "..", ".."),
      renderer: "@fastify/react",
      dev: process.argv.includes("--dev"),
    });
    await fastify.vite.ready();
});

My client entry sits in

src/routes/client

Server sits in src/server.ts

The output in dist currently is dist/routes/client

And the files that get created are index.html, /.vite, /assets

Build script

"build": "rollup -c && vite build",

Rollup just handles the folder structure and the js, ts files. Doesn't copy anything else over