diff --git a/packages/core/integration-tests/test/hmr.js b/packages/core/integration-tests/test/hmr.js index 72de557d571..66794f361db 100644 --- a/packages/core/integration-tests/test/hmr.js +++ b/packages/core/integration-tests/test/hmr.js @@ -830,5 +830,68 @@ module.hot.dispose((data) => { } } }); + + it('should handle CSS Modules update correctly', async () => { + let testDir = path.join(__dirname, '/input'); + await overlayFS.rimraf(testDir); + await overlayFS.mkdirp(testDir); + await ncp(path.join(__dirname, '/integration/hmr-css-modules'), testDir); + + let port = await getPort(); + let b = bundler(path.join(testDir, 'index.html'), { + inputFS: overlayFS, + outputFS: overlayFS, + serveOptions: { + https: false, + port, + host: '127.0.0.1', + }, + hmrOptions: {port}, + shouldContentHash: false, + config, + }); + + subscription = await b.watch(); + let bundleEvent = await getNextBuild(b); + assert.equal(bundleEvent.type, 'buildSuccess'); + + let window; + try { + let dom = await JSDOM.JSDOM.fromURL( + 'http://127.0.0.1:' + port + '/index.html', + { + runScripts: 'dangerously', + resources: 'usable', + pretendToBeVisual: true, + }, + ); + let _window = (window = dom.window); // For Flow + window.WebSocket = WebSocket; + await new Promise(res => + dom.window.document.addEventListener('load', () => { + res(); + }), + ); + _window.console.clear = () => {}; + _window.console.warn = () => {}; + + let initialHref = _window.document.querySelector('link').href; + + await overlayFS.copyFile( + path.join(testDir, 'index2.module.css'), + path.join(testDir, 'index.module.css'), + ); + assert.equal((await getNextBuild(b)).type, 'buildSuccess'); + await sleep(200); + + let newHref = _window.document.querySelector('link').href; + + assert.notStrictEqual(initialHref, newHref); + } finally { + if (window) { + window.close(); + } + } + }); }); }); diff --git a/packages/core/integration-tests/test/integration/hmr-css-modules/index.html b/packages/core/integration-tests/test/integration/hmr-css-modules/index.html new file mode 100644 index 00000000000..d704da1e934 --- /dev/null +++ b/packages/core/integration-tests/test/integration/hmr-css-modules/index.html @@ -0,0 +1,10 @@ + + + + + + +
+ + + diff --git a/packages/core/integration-tests/test/integration/hmr-css-modules/index.jsx b/packages/core/integration-tests/test/integration/hmr-css-modules/index.jsx new file mode 100644 index 00000000000..9890fe63081 --- /dev/null +++ b/packages/core/integration-tests/test/integration/hmr-css-modules/index.jsx @@ -0,0 +1,3 @@ +import * as styles from "./index.module.css"; + +const Hello = () =>
hello
; diff --git a/packages/core/integration-tests/test/integration/hmr-css-modules/index.module.css b/packages/core/integration-tests/test/integration/hmr-css-modules/index.module.css new file mode 100644 index 00000000000..7590fad04cf --- /dev/null +++ b/packages/core/integration-tests/test/integration/hmr-css-modules/index.module.css @@ -0,0 +1,3 @@ +.hello { + background: red; +} diff --git a/packages/core/integration-tests/test/integration/hmr-css-modules/index2.module.css b/packages/core/integration-tests/test/integration/hmr-css-modules/index2.module.css new file mode 100644 index 00000000000..bc09ce18ce6 --- /dev/null +++ b/packages/core/integration-tests/test/integration/hmr-css-modules/index2.module.css @@ -0,0 +1,3 @@ +.hello { + background: blue; +} diff --git a/packages/reporters/dev-server/src/HMRServer.js b/packages/reporters/dev-server/src/HMRServer.js index 76a16bca296..44a6e4196a9 100644 --- a/packages/reporters/dev-server/src/HMRServer.js +++ b/packages/reporters/dev-server/src/HMRServer.js @@ -100,7 +100,7 @@ export default class HMRServer { let queue = new PromiseQueue({maxConcurrent: FS_CONCURRENCY}); for (let asset of changedAssets) { - if (asset.type !== 'js') { + if (asset.type !== 'js' && asset.type !== 'css') { // If all of the incoming dependencies of the asset actually resolve to a JS asset // rather than the original, we can mark the runtimes as changed instead. URL runtimes // have a cache busting query param added with HMR enabled which will trigger a reload.