Reputation: 7689
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
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