I've got a vite project that's serving a tiny web app with web components.
For some technical reasons, I'd like to be able to hit a URL and get vite to serve me an up-to-date version of a source file. For example, if the file is in ./src/some-file.mjs
I would like to be able to have a web component that hits
<!-- any URL is fine, this is just an example -->
<my-component src="localhost:3000/src/some-file.mjs"></my-component>
I'd also be ok with referencing the file directly:
<!-- any URL is fine, this is just an example -->
<my-component src="./src/some-file.mjs"></my-component>
The challenge there is that I'm using dynamic import inside my-component and treating the value of the src
attribute as a url (which will be the normal case outside of development... maybe a CDN or similar).
I'd like HMR-- so when I update the file it triggers a reload and the web-component re-renders and the new source is downloaded and the ui is updated.
So far I've gotten it to serve the ./dist dir. It doesn't give me HMR, and it also caches pretty hard so even when I rebuild dist, I have to restart the server to serve the new content. Not ideal.
import { defineConfig } from 'vite';
import litPlugin from 'rollup-plugin-lit-css';
export default defineConfig({
plugins: [litPlugin()],
build: {
lib: {
entry: 'src/one-file.mjs',
name: 'OneFile',
formats: ['es', 'umd'], // Generate ES module and UMD builds
fileName: (format) => `one-file.${format}.js`
},
rollupOptions: {
// Additional Rollup options if needed
}
},
server: {
// Serve files from the ./dist directory
fs: {
// Disable strict serving behavior to allow serving from outside root
strict: false,
// Specify directories that should be accessible to the server
allow: ['./dist']
}
}
});
My best guess about how to get this is to see if Vite can serve compiled source from a URL, then target that URL with the src
attribute.
Any tips?
Fundamentally, your problem boils down to a custom setup. Out-of-box, Vite cannot achieve this kind of workflow. But fortunately, Vite provides official guide for custom backend which you can utilize. In summary, your problem can be broken down into following concrete steps:
dev
mode, instead use thevite build
withwatch
mode. This shall ensure that compiled files are generated on the disk.) Also, write simple a plugin that will generate aversion.txt
file which you can poll.build
mode with additionalwatch
means that your compilation will happen automatically on file change, but you will not be able to use Vite's custom server and it also implies no HMR.A very simple Vite configuration would be as following. Note the use of empty
watch
object passed to thebuild
configuration:Second, we will create a static file server with Node's
http
module. The important part is to ignore thetimestamp
that we will be sending from the browser along with a file request.Finally, let's write some client-side code to do the polling and reload when the content changes:
Now, this is the gist of the problem. You can enhance this with more customizations like:
<head>
tag. If you need global replacement, the trick is to use<style>
tag with some fixedid
with which you can delete and update the existing styling with the new styling supplied by the HMR updates. In other cases, you can trigger full page refresh and persist the state insessionStorage
orlocalStorage
which you can then read again after full page reload.