vite plugin hot reload for static assets and watchChange function clarifications #8364
-
Hello I am building a
Folder structure (simplified):
plugin import {PluginOption} from "vite";
import fs from "fs";
import path from 'path'
import type {GenerateFilesManifestConfigType, MatterOutputType} from './types'
import {ChangeEvent, NormalizedInputOptions} from "rollup";
export default function generateFilesManifest(userConfig: GenerateFilesManifestConfigType): PluginOption {
let config: GenerateFilesManifestConfigType = userConfig
let rootDir: string
let publicDir: string
function generateManifest() {
// logic that generates manifest file here
}
return {
name: 'generate-files-manifest',
configResolved(resolvedConfig) {
publicDir = resolvedConfig.publicDir
rootDir = resolvedConfig.root
},
buildStart(options: NormalizedInputOptions) {
generateManifest();
},
handleHotUpdate({file, server}) {
if (file.includes(config.watchDirectory) && file.endsWith('.md')) {
generateManifest();
}
},
watchChange(id: string, change: { event: ChangeEvent }) {
console.log('CHANGE')
}
}
} plugin types export type GenerateFilesManifestConfigType = {
watchDirectory: string,
output: string
}
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import fs from "fs";
import path from "path";
import generateFilesManifest from "./vite_plugins/generateFilesManifest";
export default defineConfig({
plugins: [
vue(),
generateFilesManifest({
watchDirectory: '/public/watchir',
output: './public/docs.json'
})
],
resolve: {
alias: {
"/@": path.resolve(__dirname, "./src"),
"/~": path.resolve(__dirname, "./"),
},
}
}) Main <script lang="ts">
import {onMounted, ref, Ref} from 'vue';
import {MatterOutputType} from "/~/vite_plugins/types";
export default {
setup() {
const posts: Ref<MatterOutputType[]> = ref([])
fetch('docs.json')
.then(r => r.json())
.then(json => {
const docs = json as MatterOutputType[]
posts.value = docs
})
return {
posts
}
}
}
</script>
<template>
<div>
<h1>Home</h1>
<ul><li v-for="post of posts">{{ post.body }}</li></ul>
</div>
</template> Issue 1 - hot-reload on static assets change not workingWhenever I update (does not trigger on file creation it seems) any files in I have managed to fix the issue, by, instead of using the import docs from '../../public/docs.json';
export default {
setup() {
const posts: Ref<MatterOutputType[]> = ref([])
onMounted(() => {
const typedPosts = docs as MatterOutputType[]
posts.value = typedPosts
})
return {
posts
}
}
} However, I cannot use the import always. In some cases I want the content to be loaded dynamically by Maybe it's possible to invoke some action from Issue 2 -
|
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 4 replies
-
Issue 2 was solved with buildStart(options: NormalizedInputOptions) {
generateManifest();
if (command === 'serve') {
const watchDirFullPath = path.join(rootDir, config.watchDirectory)
watcher = chokidar.watch(watchDirFullPath,
{
ignoreInitial: true
}
);
watcher
.on('add', function (path) {
//console.log('File', path, 'has been added');
generateManifest();
})
.on('change', function (path) {
//console.log('File', path, 'has been changed');
generateManifest();
})
.on('unlink', function (path) {
//console.log('File', path, 'has been removed');
generateManifest();
})
.on('error', function (error) {
console.error('Error happened', error);
})
}
},
buildEnd(err?: Error) {
watcher?.close();
}, Issue 1 is still open.. |
Beta Was this translation helpful? Give feedback.
-
stale, no answer.. closing |
Beta Was this translation helpful? Give feedback.
-
I don't think |
Beta Was this translation helpful? Give feedback.
-
Came across this just now. I know the answer is closed, but for anyone else with this issue I solved it by accessing the watcher instance on the dev server e.g. export default function myPlugin(config) {
return {
name: 'my-plugin',
configureServer(server) {
function onWatchChange(filepath) {
// do stuff here...
}
server.watcher.on('add', onWatchChange);
server.watcher.on('unlink', onWatchChange);
}
};
} |
Beta Was this translation helpful? Give feedback.
-
Adding a concrete example here - my use case was just to auto reload a regular static css file on a non-React scratchpad project based off the react-ts template: // vite.config.ts
import { ViteDevServer, defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
function customWatcher(options: { filePaths: string[] } = { filePaths: [] }) {
return {
name: 'custom-watcher',
configureServer(server: ViteDevServer) {
options.filePaths.forEach((f) => {
server.watcher.add(f);
});
function onWatchChange(_: string) {
server.hot.send({ type: 'full-reload' });
}
server.watcher.on('add', onWatchChange);
server.watcher.on('unlink', onWatchChange);
server.watcher.on('change', onWatchChange);
},
};
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), customWatcher({ filePaths: ['./public/styles.css'] })],
}); I might be doing something silly/inefficient here but it works perfectly well for the use case. |
Beta Was this translation helpful? Give feedback.
stale, no answer.. closing