Skip to content

Commit

Permalink
Update refresh utils for Remix support (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBarre authored Jan 31, 2024
1 parent a847abe commit 53ecc44
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
2 changes: 1 addition & 1 deletion playground/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test("HMR invalidate", async ({ page }) => {
// Edit export
editFile("src/TitleWithExport.tsx", ["React", "React!"]);
await waitForLogs(
"[vite] invalidate /src/TitleWithExport.tsx: Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports",
'[vite] invalidate /src/TitleWithExport.tsx: Could not Fast Refresh ("framework" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports',
"[vite] hot updated: /src/App.tsx",
);
await expect(page.locator("h1")).toHaveText("Vite * React!");
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
RefreshRuntime.registerExportsForReactRefresh("${id}", currentExports);
import.meta.hot.accept((nextExports) => {
if (!nextExports) return;
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports);
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate("${id}", currentExports, nextExports);
if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
});
});
Expand Down
39 changes: 31 additions & 8 deletions src/refresh-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -581,41 +581,64 @@ function debounce(fn, delay) {
};
}

const enqueueUpdate = debounce(performReactRefresh, 16);
const hooks = [];
window.__registerBeforePerformReactRefresh = (cb) => {
hooks.push(cb);
};
const enqueueUpdate = debounce(async () => {
if (hooks.length) await Promise.all(hooks.map((cb) => cb()));
performReactRefresh();
}, 16);

export function validateRefreshBoundaryAndEnqueueUpdate(
id,
prevExports,
nextExports,
) {
if (!predicateOnExport(prevExports, (key) => key in nextExports)) {
const ignoredExports = window.__getReactRefreshIgnoredExports?.({ id }) ?? [];
if (
predicateOnExport(
ignoredExports,
prevExports,
(key) => key in nextExports,
) !== true
) {
return "Could not Fast Refresh (export removed)";
}
if (!predicateOnExport(nextExports, (key) => key in prevExports)) {
if (
predicateOnExport(
ignoredExports,
nextExports,
(key) => key in prevExports,
) !== true
) {
return "Could not Fast Refresh (new export)";
}

let hasExports = false;
const allExportsAreComponentsOrUnchanged = predicateOnExport(
ignoredExports,
nextExports,
(key, value) => {
hasExports = true;
if (isLikelyComponentType(value)) return true;
return prevExports[key] === nextExports[key];
},
);
if (hasExports && allExportsAreComponentsOrUnchanged) {
if (hasExports && allExportsAreComponentsOrUnchanged === true) {
enqueueUpdate();
} else {
return "Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports";
return `Could not Fast Refresh ("${allExportsAreComponentsOrUnchanged}" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports`;
}
}

function predicateOnExport(moduleExports, predicate) {
function predicateOnExport(ignoredExports, moduleExports, predicate) {
for (const key in moduleExports) {
if (key === "__esModule") continue;
if (ignoredExports.includes(key)) continue;
const desc = Object.getOwnPropertyDescriptor(moduleExports, key);
if (desc && desc.get) return false;
if (!predicate(key, moduleExports[key])) return false;
if (desc && desc.get) return key;
if (!predicate(key, moduleExports[key])) return key;
}
return true;
}
Expand Down

0 comments on commit 53ecc44

Please sign in to comment.