vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
65 lines (62 loc) • 10.1 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { useCallback, useEffect } from 'react';
import { RSC_HMR_EVENT } from './createReactFetcher.js';
import { env } from './env.js';
function refreshCssLinks(data) {
if (!data || typeof document === "undefined") return false;
const rel = String(data.file || "").replace(/^[\\/]+/, "");
if (!rel) return false;
const basename = rel.split(/[\\/]/).pop();
const links = document.querySelectorAll('link[rel="stylesheet"]');
let refreshed = 0;
links.forEach((link) => {
const href = link.getAttribute("href");
if (!href) return;
let pathname;
try {
pathname = new URL(href, window.location.origin).pathname;
} catch {
pathname = href.split("?")[0] ?? "";
}
const matches = pathname.endsWith("/" + rel) || pathname.endsWith(rel) || !!basename && pathname.endsWith("/" + basename);
if (!matches) return;
const url = new URL(href, window.location.origin);
url.searchParams.set("t", String(Date.now()));
link.setAttribute("href", url.pathname + url.search);
refreshed++;
});
return refreshed > 0;
}
function useRscHmr(refetch, options = {}) {
const { verbose = env.DEV, filter } = options;
const handler = useCallback(
(data) => {
if (filter && !filter(data)) return;
const kind = data.kind;
if (verbose) {
console.log("[RSC HMR] Server component updated:", data.file, kind ? `(${kind})` : "");
}
if (kind === "css") {
refreshCssLinks(data);
}
refetch(window.location.pathname);
},
[refetch, verbose, filter]
);
useEffect(() => {
if (typeof import.meta.hot === "undefined") return;
import.meta.hot.on(RSC_HMR_EVENT, handler);
if (verbose) {
console.log("[RSC HMR] Listening for server component updates");
}
return () => {
import.meta.hot.off(RSC_HMR_EVENT, handler);
};
}, [handler, verbose]);
}
export { useRscHmr };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlUnNjSG1yLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vdXRpbHMvdXNlUnNjSG1yLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZUVmZmVjdCwgdXNlQ2FsbGJhY2sgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IFJTQ19ITVJfRVZFTlQgfSBmcm9tIFwiLi9jcmVhdGVSZWFjdEZldGNoZXIuanNcIjtcbmltcG9ydCB0eXBlIHsgUnNjSG1yRGF0YSB9IGZyb20gXCIuL2NyZWF0ZVJlYWN0RmV0Y2hlci5qc1wiO1xuaW1wb3J0IHsgZW52IH0gZnJvbSBcIi4vZW52LmpzXCI7XG5cbi8vIE1pcnJvciBvZiByZWZyZXNoQ3NzTGlua3MgaW4gdmlydHVhbFJzY0htclBsdWdpbi50cyAoc2VlIGNvbW1lbnQgdGhlcmUpLlxuLy8gZGF0YS5maWxlIGlzIHRoZSBwcm9qZWN0LXJlbGF0aXZlIHBhdGggKGVnIFwic3JjL2Nzcy85bW1jLm1vZHVsZS5jc3NcIikgYW5kXG4vLyB0aGUgbGluayBocmVmIGlzIGEgVVJMIHdob3NlIHBhdGhuYW1lIGVuZHMgd2l0aCB0aGUgc2FtZSBzdWZmaXguXG4vLyBGYWxscyBiYWNrIHRvIGJhc2VuYW1lIG1hdGNoaW5nIGZvciBlZGdlIGNhc2VzIHdoZXJlIHRoZSBwcm9qZWN0LXJlbGF0aXZlXG4vLyBmb3JtIGRvZXNuJ3QgYXBwZWFyIHZlcmJhdGltIGluIHRoZSBocmVmLlxuZnVuY3Rpb24gcmVmcmVzaENzc0xpbmtzKGRhdGE6IFJzY0htckRhdGEpOiBib29sZWFuIHtcbiAgaWYgKCFkYXRhIHx8IHR5cGVvZiBkb2N1bWVudCA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGZhbHNlO1xuICBjb25zdCByZWwgPSBTdHJpbmcoZGF0YS5maWxlIHx8IFwiXCIpLnJlcGxhY2UoL15bXFxcXC9dKy8sIFwiXCIpO1xuICBpZiAoIXJlbCkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBiYXNlbmFtZSA9IHJlbC5zcGxpdCgvW1xcXFwvXS8pLnBvcCgpO1xuICBjb25zdCBsaW5rcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2xpbmtbcmVsPVwic3R5bGVzaGVldFwiXScpO1xuICBsZXQgcmVmcmVzaGVkID0gMDtcbiAgbGlua3MuZm9yRWFjaCgobGluaykgPT4ge1xuICAgIGNvbnN0IGhyZWYgPSBsaW5rLmdldEF0dHJpYnV0ZShcImhyZWZcIik7XG4gICAgaWYgKCFocmVmKSByZXR1cm47XG4gICAgbGV0IHBhdGhuYW1lOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIHBhdGhuYW1lID0gbmV3IFVSTChocmVmLCB3aW5kb3cubG9jYXRpb24ub3JpZ2luKS5wYXRobmFtZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHBhdGhuYW1lID0gaHJlZi5zcGxpdChcIj9cIilbMF0gPz8gXCJcIjtcbiAgICB9XG4gICAgY29uc3QgbWF0Y2hlcyA9XG4gICAgICBwYXRobmFtZS5lbmRzV2l0aChcIi9cIiArIHJlbCkgfHxcbiAgICAgIHBhdGhuYW1lLmVuZHNXaXRoKHJlbCkgfHxcbiAgICAgICghIWJhc2VuYW1lICYmIHBhdGhuYW1lLmVuZHNXaXRoKFwiL1wiICsgYmFzZW5hbWUpKTtcbiAgICBpZiAoIW1hdGNoZXMpIHJldHVybjtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGhyZWYsIHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pO1xuICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KFwidFwiLCBTdHJpbmcoRGF0ZS5ub3coKSkpO1xuICAgIGxpbmsuc2V0QXR0cmlidXRlKFwiaHJlZlwiLCB1cmwucGF0aG5hbWUgKyB1cmwuc2VhcmNoKTtcbiAgICByZWZyZXNoZWQrKztcbiAgfSk7XG4gIHJldHVybiByZWZyZXNoZWQgPiAwO1xufVxuXG4vKipcbiAqIFJlYWN0IGhvb2sgZm9yIFJTQyBITVIgKEhvdCBNb2R1bGUgUmVwbGFjZW1lbnQpLlxuICogXG4gKiBXaGVuIGEgc2VydmVyIGNvbXBvbmVudCBmaWxlIGNoYW5nZXMsIHRoaXMgaG9vayBjYWxscyB5b3VyIGByZWZldGNoYCBmdW5jdGlvblxuICogdG8gcmUtZmV0Y2ggdGhlIFJTQyBzdHJlYW0uIENvbWJpbmVkIHdpdGggYHN0YXJ0VHJhbnNpdGlvbmAsIHRoaXMgcHJlc2VydmVzXG4gKiBjbGllbnQgY29tcG9uZW50IHN0YXRlIHdoaWxlIHVwZGF0aW5nIHNlcnZlci1yZW5kZXJlZCBjb250ZW50LlxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHN4XG4gKiBpbXBvcnQgeyB1c2VSc2NIbXIgfSBmcm9tICd2aXRlLXBsdWdpbi1yZWFjdC1zZXJ2ZXIvdXRpbHMnO1xuICogXG4gKiBmdW5jdGlvbiBTaGVsbCh7IGRhdGEgfSkge1xuICogICBjb25zdCBbc3RvcmVEYXRhLCBzZXRTdG9yZURhdGFdID0gdXNlU3RhdGUoZGF0YSk7XG4gKiAgIFxuICogICBjb25zdCByZWZldGNoID0gdXNlQ2FsbGJhY2soKHVybDogc3RyaW5nKSA9PiB7XG4gKiAgICAgc3RhcnRUcmFuc2l0aW9uKCgpID0+IHtcbiAqICAgICAgIHNldFN0b3JlRGF0YShjcmVhdGVSZWFjdEZldGNoZXIoeyB1cmwgfSkpO1xuICogICAgIH0pO1xuICogICB9LCBbXSk7XG4gKiAgIFxuICogICAvLyBSZWZldGNoIFJTQyBzdHJlYW0gd2hlbiBzZXJ2ZXIgY29tcG9uZW50cyBjaGFuZ2VcbiAqICAgdXNlUnNjSG1yKHJlZmV0Y2gpO1xuICogICBcbiAqICAgcmV0dXJuIDw+e3VzZShzdG9yZURhdGEpfTwvPjtcbiAqIH1cbiAqIGBgYFxuICogXG4gKiBAcGFyYW0gcmVmZXRjaCAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBzZXJ2ZXIgY29tcG9uZW50cyBjaGFuZ2UuIFxuICogICBSZWNlaXZlcyB0aGUgY3VycmVudCBwYXRobmFtZS4gVXNlIGBzdGFydFRyYW5zaXRpb25gIGluc2lkZSBmb3Igc21vb3RoIHVwZGF0ZXMuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVJzY0htcihcbiAgcmVmZXRjaDogKHVybDogc3RyaW5nKSA9PiB2b2lkLFxuICBvcHRpb25zOiB7XG4gICAgLyoqIFdoZXRoZXIgdG8gbG9nIEhNUiBldmVudHMuIEBkZWZhdWx0IHRydWUgaW4gZGV2ICovXG4gICAgdmVyYm9zZT86IGJvb2xlYW47XG4gICAgLyoqIEN1c3RvbSBmaWx0ZXIg4oCUIHJldHVybiBmYWxzZSB0byBza2lwIHJlZmV0Y2ggZm9yIHNwZWNpZmljIGZpbGVzICovXG4gICAgZmlsdGVyPzogKGRhdGE6IFJzY0htckRhdGEpID0+IGJvb2xlYW47XG4gIH0gPSB7fVxuKSB7XG4gIGNvbnN0IHsgdmVyYm9zZSA9IGVudi5ERVYsIGZpbHRlciB9ID0gb3B0aW9ucztcblxuICBjb25zdCBoYW5kbGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKGRhdGE6IFJzY0htckRhdGEpID0+IHtcbiAgICAgIGlmIChmaWx0ZXIgJiYgIWZpbHRlcihkYXRhKSkgcmV0dXJuO1xuICAgICAgY29uc3Qga2luZCA9IChkYXRhIGFzIHsga2luZD86IHN0cmluZyB9KS5raW5kO1xuICAgICAgaWYgKHZlcmJvc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tSU0MgSE1SXSBTZXJ2ZXIgY29tcG9uZW50IHVwZGF0ZWQ6JywgZGF0YS5maWxlLCBraW5kID8gYCgke2tpbmR9KWAgOiAnJyk7XG4gICAgICB9XG4gICAgICBpZiAoa2luZCA9PT0gJ2NzcycpIHtcbiAgICAgICAgcmVmcmVzaENzc0xpbmtzKGRhdGEpO1xuICAgICAgfVxuICAgICAgcmVmZXRjaCh3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpO1xuICAgIH0sXG4gICAgW3JlZmV0Y2gsIHZlcmJvc2UsIGZpbHRlcl1cbiAgKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICh0eXBlb2YgaW1wb3J0Lm1ldGEuaG90ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuXG4gICAgaW1wb3J0Lm1ldGEuaG90Lm9uKFJTQ19ITVJfRVZFTlQsIGhhbmRsZXIpO1xuICAgIFxuICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICBjb25zb2xlLmxvZygnW1JTQyBITVJdIExpc3RlbmluZyBmb3Igc2VydmVyIGNvbXBvbmVudCB1cGRhdGVzJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGltcG9ydC5tZXRhLmhvdCEub2ZmKFJTQ19ITVJfRVZFTlQsIGhhbmRsZXIpO1xuICAgIH07XG4gIH0sIFtoYW5kbGVyLCB2ZXJib3NlXSk7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBVUEsU0FBUyxnQkFBZ0IsSUFBMkIsRUFBQTtBQUNsRCxFQUFBLElBQUksQ0FBQyxJQUFBLElBQVEsT0FBTyxRQUFBLEtBQWEsYUFBb0IsT0FBQSxLQUFBO0FBQy9DLEVBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxJQUFLLENBQUEsSUFBQSxJQUFRLEVBQUUsQ0FBRSxDQUFBLE9BQUEsQ0FBUSxXQUFXLEVBQUUsQ0FBQTtBQUNyRCxFQUFBLElBQUEsQ0FBQyxLQUFZLE9BQUEsS0FBQTtBQUNqQixFQUFBLE1BQU0sUUFBVyxHQUFBLEdBQUEsQ0FBSSxLQUFNLENBQUEsT0FBTyxFQUFFLEdBQUksRUFBQTtBQUNsQyxFQUFBLE1BQUEsS0FBQSxHQUFRLFFBQVMsQ0FBQSxnQkFBQSxDQUFpQix3QkFBd0IsQ0FBQTtBQUNoRSxFQUFBLElBQUksU0FBWSxHQUFBLENBQUE7QUFDVixFQUFBLEtBQUEsQ0FBQSxPQUFBLENBQVEsQ0FBQyxJQUFTLEtBQUE7QUFDaEIsSUFBQSxNQUFBLElBQUEsR0FBTyxJQUFLLENBQUEsWUFBQSxDQUFhLE1BQU0sQ0FBQTtBQUNyQyxJQUFBLElBQUksQ0FBQyxJQUFNLEVBQUE7QUFDUCxJQUFBLElBQUEsUUFBQTtBQUNBLElBQUEsSUFBQTtBQUNGLE1BQUEsUUFBQSxHQUFXLElBQUksR0FBSSxDQUFBLElBQUEsRUFBTSxNQUFPLENBQUEsUUFBQSxDQUFTLE1BQU0s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