diff --git a/lib/hot-api.js b/lib/hot-api.js index 755c9582..7450a44b 100644 --- a/lib/hot-api.js +++ b/lib/hot-api.js @@ -44,12 +44,12 @@ if (!g[globalKey]) { }; } -const runAcceptHandlers = acceptHandlers => { +const runAcceptHandlers = (acceptHandlers, bubbled) => { const queue = [...acceptHandlers]; const next = () => { const cur = queue.shift(); if (cur) { - return cur(null).then(next); + return cur({ bubbled }).then(next); } else { return Promise.resolve(null); } @@ -57,15 +57,25 @@ const runAcceptHandlers = acceptHandlers => { return next(); }; +const isBubbled = (children, lastChildren) => { + if (children.length !== lastChildren.length) return false; + return children.some((x, i) => x !== lastChildren[i]); +}; + export const applyHmr = makeApplyHmr(args => { const { notifyStart, notifyError, notifyEnd } = g[globalKey]; const { m, reload } = args; - let acceptHandlers = (m.hot.data && m.hot.data.acceptHandlers) || []; - let nextAcceptHandlers = []; + const acceptHandlers = (m.hot.data && m.hot.data.acceptHandlers) || []; + const nextAcceptHandlers = []; + + const children = m.children.map(x => require.cache[x]); + + const lastChildren = m.hot.data && m.hot.data.children; m.hot.dispose(data => { data.acceptHandlers = nextAcceptHandlers; + data.children = children; }); const dispose = (...args) => m.hot.dispose(...args); @@ -81,7 +91,11 @@ export const applyHmr = makeApplyHmr(args => { if (status === 'ready') { notifyStart(); } else if (status === 'idle') { - runAcceptHandlers(acceptHandlers) + const bubbled = + acceptHandlers.length > 0 + ? isBubbled(children, lastChildren) + : undefined; + runAcceptHandlers(acceptHandlers, bubbled) .then(notifyEnd) .catch(notifyError(reload)); }