Corrl
Corrl

Reputation: 7689

How to configure Svelte project with Vite so that the static files are not copied during the build?

In a NORMAL Svelte project (no SvelteKit) the static files are in the public directory and when running npm run build (rollup -c) the src folder is compiled into public/build and the public folder can then be hosted somewhere.

I now switched (an already existing) Svelte project to Vite and the static files are still under public but when running npm run build (vite build), everything is bundled into the dist directory. So all the files in the public directory are actually copied and exist twice in the project. Which means when changing or adding something (which doesn't effect the app logic) the project needs to be rebuild before it can be redeployed.

Can this be changed via the configuration, that either all compiled files are added again to the public directory or that the static files reside directly inside dist and nothing is copied during the build process?

Edit: The project should still be able to be run in dev mode npm run dev (vite) with the assets being served

Upvotes: 3

Views: 8912

Answers (1)

Allan Chain
Allan Chain

Reputation: 2815

Yes you can keep public files in dist without copying, but it's a little "hacking".

First you need to disable publicDir option to disable copying.

Then disable emptyOutdir to reserve files.

Finally you may want to clean old assets, so a buildStart hook is added, cleaning dist/assets when build starts.

The final vite.config.js (you may want to add some error handling):

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import { rm } from 'fs/promises'

// https://vitejs.dev/config/
export default defineConfig(({ command }) => ({
  plugins: [
    svelte(),
    {
      buildStart() {
        if (command === 'build')
          rm('./dist/assets', { recursive: true }).catch(() => {})
      }
    },
  ],
  publicDir: false,
  build: {
    emptyOutDir: false,
  }
}))

Update: To serve those files in npm run dev, extra hacks are required. You need to create a custom server to achieve that. (Vite doesn't seem to provide a configuration approach.)

server.js:

import express from 'express'
import { createServer as createViteServer } from 'vite'

// Or use require if nodejs complains about ES module
// const express = require('express')
// const { createServer: createViteServer } = require('vite')

async function createServer() {
  const app = express()

  // Create Vite server in middleware mode.
  const vite = await createViteServer({
    server: { middlewareMode: 'html'},
  })

  // Do not serve built index.html when visiting http://localhost:3000/
  app.use(express.static('dist', { index: false }))

  // Use vite's connect instance as middleware
  app.use(vite.middlewares)

  app.listen(3000)
}

createServer()

And replace "dev": "vite" with "dev": "node server.js" in package.json

Upvotes: 4

Related Questions