I have a very large JSON file that is generated at build time with data.
I need to fetch this JSON file in my frontend code.
After looking through the documentation, I believe I need to use a plugin to do this.
Here's my plugin:
export function buildJsonFilesPlugin(): VitePlugin {
const myJSON = buildMyJson();
const source = JSON.stringify(myJSON);
return {
name: "vite-plugin-my-json-builder",
configureServer(server) {
server.middlewares.use(async (req, res, next) => {
if (req.url?.includes("generated-data/FILE.json")) {
res.setHeader("Content-Type", "application/json");
res.end(source);
return;
}
next();
});
},
generateBundle() {
console.log("Building JSON files...");
const output = this.emitFile({
type: "asset",
needsCodeReference: true,
source,
name: "FILE.json",
});
console.log("Emitted target JSON file with reference ID:", output);
console.log("Finished building JSON files!");
},
};
}
Then, I try to reference it in my code like so:
const url = new URL("generated-data/FILE.json", import.meta.url).toString();
await fetch(url).then(res => res.json()).then((json) => {
console.log("Fetched FILE at: ", url);
console.log("Contents are: ", json);
});
Now, because of the configureServer, this does work with local development. However, the filename in the code snippet is not replaced in the bundled output (when I run vite build).
Perplexingly, the file itself is output to dist/assets/generated-data/FILE-[hash].json (with [HASH]) suitably replaced.
I have been wresting with this trying to figure out how to get vite to not say that new URL("FILE.json", import.meta.url) "doesn't exist at build time"