diff --git a/.changeset/large-apes-perform.md b/.changeset/large-apes-perform.md
new file mode 100644
index 000000000..8eacbe717
--- /dev/null
+++ b/.changeset/large-apes-perform.md
@@ -0,0 +1,5 @@
+---
+'wmr': patch
+---
+
+Fix case where the module-graph would become stale if two co-dependent modules would import the same file, when this file would get updated we'd only cache-bust the import in one of those two files making the graph stale. One file updates the old version and the other updates the new one.
diff --git a/packages/wmr/demo/public/index.tsx b/packages/wmr/demo/public/index.tsx
index 813fe2710..b6f2d1cf0 100644
--- a/packages/wmr/demo/public/index.tsx
+++ b/packages/wmr/demo/public/index.tsx
@@ -53,4 +53,4 @@ export async function prerender(data) {
}
// @ts-ignore
-if (module.hot) module.hot.accept(u => render(, document.body));
+if (module.hot) module.hot.accept(u => hydrate(, document.body));
diff --git a/packages/wmr/demo/public/lib/loc.js b/packages/wmr/demo/public/lib/loc.js
index 2766ae276..31813dd2d 100644
--- a/packages/wmr/demo/public/lib/loc.js
+++ b/packages/wmr/demo/public/lib/loc.js
@@ -39,7 +39,6 @@ export const exec = (url, route, matches) => {
return matches;
};
-
export function LocationProvider(props) {
const [url, route] = useReducer(UPDATE, location.pathname + location.search);
diff --git a/packages/wmr/src/lib/websocket-server.js b/packages/wmr/src/lib/websocket-server.js
index a6aa70e79..fd01a5c79 100644
--- a/packages/wmr/src/lib/websocket-server.js
+++ b/packages/wmr/src/lib/websocket-server.js
@@ -19,12 +19,14 @@ export default class WebSocketServer extends ws.Server {
client.on('message', function (data) {
const message = JSON.parse(data.toString());
if (message.type === 'hotAccepted') {
- if (!moduleGraph.has(message.id)) {
- moduleGraph.set(message.id, { dependencies: new Set(), dependents: new Set(), acceptingUpdates: false });
+ const [id] = message.id.split('?');
+ if (!moduleGraph.has(id)) {
+ moduleGraph.set(id, { dependencies: new Set(), dependents: new Set(), acceptingUpdates: false });
}
- const entry = moduleGraph.get(message.id);
+ const entry = moduleGraph.get(id);
entry.acceptingUpdates = true;
+ entry.stale = false;
}
});
}
diff --git a/packages/wmr/src/wmr-middleware.js b/packages/wmr/src/wmr-middleware.js
index 4714dc83e..81b1f56f4 100644
--- a/packages/wmr/src/wmr-middleware.js
+++ b/packages/wmr/src/wmr-middleware.js
@@ -399,7 +399,6 @@ export const TRANSFORMS = {
const specModule = moduleGraph.get(modSpec);
specModule.dependents.add(importer);
if (specModule.stale) {
- specModule.stale = false;
return spec + `?t=${Date.now()}`;
}
diff --git a/packages/wmr/test/fixtures.test.js b/packages/wmr/test/fixtures.test.js
index e59294929..0af312d19 100644
--- a/packages/wmr/test/fixtures.test.js
+++ b/packages/wmr/test/fixtures.test.js
@@ -248,6 +248,30 @@ describe('fixtures', () => {
expect(text).toEqual('3');
});
+ it('should bubble up updates in non-accepted files with multiple parents', async () => {
+ await loadFixture('hmr', env);
+ instance = await runWmrFast(env.tmp.path);
+ await getOutput(env, instance);
+
+ let homeFoo = await env.page.$('#home-foo');
+ let rootFoo = await env.page.$('#root-foo');
+ let homeText = homeFoo ? await homeFoo.evaluate(el => el.textContent) : null;
+ let rootText = rootFoo ? await rootFoo.evaluate(el => el.textContent) : null;
+ expect(homeText).toEqual('42');
+ expect(rootText).toEqual('42');
+
+ await updateFile(env.tmp.path, 'store.js', content => content.replace('42', '43'));
+
+ await timeout(2000);
+
+ homeFoo = await env.page.$('#home-foo');
+ rootFoo = await env.page.$('#root-foo');
+ homeText = homeFoo ? await homeFoo.evaluate(el => el.textContent) : null;
+ rootText = rootFoo ? await rootFoo.evaluate(el => el.textContent) : null;
+ expect(homeText).toEqual('43');
+ expect(rootText).toEqual('43');
+ });
+
it('should hot reload for a newly created file', async () => {
await loadFixture('hmr', env);
instance = await runWmrFast(env.tmp.path);
diff --git a/packages/wmr/test/fixtures/hmr/home.js b/packages/wmr/test/fixtures/hmr/home.js
index 839a1facb..211676280 100644
--- a/packages/wmr/test/fixtures/hmr/home.js
+++ b/packages/wmr/test/fixtures/hmr/home.js
@@ -1,9 +1,11 @@
+import { FOO } from './store.js';
import useCounter from './useCounter.js';
function Home() {
const [count, increment] = useCounter();
return (
+
{FOO}
Home
{count}
diff --git a/packages/wmr/test/fixtures/hmr/index.js b/packages/wmr/test/fixtures/hmr/index.js
index ff99220b9..9fbbe19e9 100644
--- a/packages/wmr/test/fixtures/hmr/index.js
+++ b/packages/wmr/test/fixtures/hmr/index.js
@@ -1,11 +1,13 @@
import { render } from 'preact';
import styles from './style.module.css';
import Home from './home.js';
+import { FOO } from './store.js';
export function App() {
return (
+ {FOO}
diff --git a/packages/wmr/test/fixtures/hmr/store.js b/packages/wmr/test/fixtures/hmr/store.js
new file mode 100644
index 000000000..e027273ee
--- /dev/null
+++ b/packages/wmr/test/fixtures/hmr/store.js
@@ -0,0 +1 @@
+export const FOO = 42;