-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
watchChange is not triggered for this.addWatchFile #14823
Comments
Could be a coincidence, we just got a PR for it: #14822 Today you can use |
Yes, this is very much a coincidence 🥳. |
This works for me in 5.0.0-beta.15 Thanks everyone! |
Could you explain your use case for future reference? |
Yes, I'm working on a plugin to enable Fable support in Vite. Imagine the follow example: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="Math.fs" />
<Compile Include="Library.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fable.Core" Version="4.2.0" />
</ItemGroup>
</Project> So it contains In my plugin, I communicate with a
module Math
let sum a b = a + b
export function sum(a, b) { return a + b;} And module App
open Fable.Core.JS
open Math
let r = sum 1 3
console.log $"meh from Fable, %i{r}"
import { sum } from "./Math.js";
import { some } from "./node_modules/fable-library/Option.js";
export const r = sum(1, 3);
console.log(some(`meh from Fable, ${r}`)); Note that the transpiled JavaScript, no longer has any notion it was once F#. The plugin looks roughly like: export default function fablePlugin({fsproj}) {
// A map of <js filePath, code>
const compilableFiles = new Map()
let projectOptions = null;
return {
name: "vite-fable-plugin",
buildStart: async function (options) {
// Initial load of the project, this will compile each file in the project to JavaScript.
// Everything happens in memory, there aren't any actual transpiled `.js` files on disk.
const projectResponse = await getProjectFile(fsproj);
projectOptions = projectResponse.ProjectOptions;
projectOptions.SourceFiles.forEach(file => {
const jsFile = file.replace('.fs','.js');
compilableFiles.set(jsFile, projectResponse.CompiledFSharpFiles[file])
});
},
resolveId: async function (source, importer, options) {
// In here I detect if an imported JavaScript file is actually a `.fs` file part of my project.
if (!source.endsWith('.js')) return null;
let fsFile = source.replace('.js', '.fs');
if(!projectOptions.SourceFiles.includes(fsFile) && importer) {
// Might be /Library.fs
const importerFolder = path.dirname(importer)
const sourceRelativePath = source.startsWith('/') ? `.${fsFile}` : fsFile;
fsFile = normalizePath(path.resolve(importerFolder, sourceRelativePath));
}
if(projectOptions.SourceFiles.includes(fsFile)) {
return fsFile.replace(fsharpFileRegex ,'.js');
}
return null;
},
load: async function (id) {
// Return the compiled JavaScript file
if (!compilableFiles.has(id)) return null;
return {
code: compilableFiles.get(id)
}
},
watchChange: async function (id, change) {
// Changes to `.fs` or `.fsproj` will eventually need to reload the transpiled JavaScript.
if (id.endsWith('.fsproj')){
// Potentially all the files in a project are invalidated.
console.log("Should reload project")
}
else if (fsharpFileRegex.test(id)) {
// I know a file changed and need to recompile it and all the dependent files in the project graph.
const compilationResult = await endpoint.send("fable/compile", { fileName: id });
const loadPromises =
Object.keys(compilationResult.CompiledFSharpFiles).map(fsFile => {
const jsFile = fsFile.replace(fsharpFileRegex ,'.js')
compilableFiles.set(jsFile, compilationResult.CompiledFSharpFiles[fsFile]);
// The result can contain multiple files, these need to be reloaded.
return this.load({ id:jsFile });
});
await Promise.all(loadPromises);
}
},
handleHotUpdate({ file, server, modules }) {
// If I know a file changed, each file that came after it in the project should be considered changed.
if(fsharpFileRegex.test(file)) {
const fileIdx = projectOptions.SourceFiles.indexOf(file);
const sourceFiles = projectOptions.SourceFiles.filter((f,idx) => idx >= fileIdx);
const modulesToCompile = [];
for (const sourceFile of sourceFiles) {
const jsFile = sourceFile.replace(fsharpFileRegex ,'.js');
const module = server.moduleGraph.getModuleById(jsFile)
if (module) modulesToCompile.push(module)
}
if (modulesToCompile.length > 0) {
server.ws.send({
type: 'custom',
event: 'hot-update-dependents',
data: modulesToCompile.map(({ url }) => url),
})
return modulesToCompile
} else {
return modules
}
}
},
buildEnd: () => {
dotnetProcess.kill();
}
}
} So, to summarize. I need to watch the I hope this makes some sense and was useful to read. |
Thanks for taking the time to write down your use case, and great to see this exploration. If you need to restart the server when non-imported files are changed, another option would be to use something like https://github.com/antfu/vite-plugin-restart. |
Yes, I was a bit surprised I didn't have to call |
Describe the bug
I'm writing a new Vite plugin and would like to watch file changes outside my bundle.
watchChange
in my plugin is not triggered.This might be related to #3474, but I don't think it is a total duplicate.
Reproduction
https://github.com/nojaf/vite-watch-plugin-repro
Steps to reproduce
npm i
npm run dev
notes.text
Expectation: see a log from the
watchChange
hook.System Info
Used Package Manager
npm
Logs
Click to expand!
Validations
The text was updated successfully, but these errors were encountered: