From 6464694a32a4f699b59814a990eda59be9b71af5 Mon Sep 17 00:00:00 2001 From: Nick Randall Date: Thu, 23 May 2019 13:40:24 -0400 Subject: [PATCH 1/3] Allow event for manually triggering a reload. This change allows the recipe described here to work: https://github.com/shellscape/webpack-plugin-serve/blob/master/recipes/watch-static-content.md --- lib/routes.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/routes.js b/lib/routes.js index d47079c..372cfd3 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -25,7 +25,7 @@ const statsOptions = { const setupRoutes = function setupRoutes() { const { app, options } = this; - const events = ['build', 'done', 'invalid', 'progress']; + const events = ['build', 'done', 'invalid', 'progress', 'reload']; const connect = async (ctx) => { if (ctx.ws) { const socket = await ctx.ws(); @@ -88,6 +88,13 @@ const setupRoutes = function setupRoutes() { socket.progress = (data) => { send(prep({ action: 'progress', data })); }; + + socket.reload = (data) => { + if (options.hmr || options.liveReload) { + const action = options.liveReload ? 'reload' : 'replace'; + send(prep({ action, data })); + } + }; for (const event of events) { this.on(event, socket[event]); From 33a9b7729e69447867d861a3faa10053eef2279a Mon Sep 17 00:00:00 2001 From: Nick Randall Date: Fri, 7 Jun 2019 10:02:40 -0400 Subject: [PATCH 2/3] Refactor reload logic to be reused --- lib/routes.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/routes.js b/lib/routes.js index 372cfd3..b30eafb 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -35,6 +35,13 @@ const setupRoutes = function setupRoutes() { } socket.send(data); }; + + const reload = (data) => { + if (options.hmr || options.liveReload) { + const action = options.liveReload ? 'reload' : 'replace'; + send(prep({ action, data })); + } + }; socket.build = (compilerName = '', { wpsId }) => { send(prep({ action: 'build', data: { compilerName, wpsId } })); @@ -71,10 +78,7 @@ const setupRoutes = function setupRoutes() { } } - if (options.hmr || options.liveReload) { - const action = options.liveReload ? 'reload' : 'replace'; - send(prep({ action, data: { hash, wpsId } })); - } + reload({ hash, wpsId }) }; socket.invalid = (filePath = '', compiler) => { @@ -90,10 +94,7 @@ const setupRoutes = function setupRoutes() { }; socket.reload = (data) => { - if (options.hmr || options.liveReload) { - const action = options.liveReload ? 'reload' : 'replace'; - send(prep({ action, data })); - } + reload(data); }; for (const event of events) { From dc13a405c72c53f8ddf92ecdc57b5d41129b18bf Mon Sep 17 00:00:00 2001 From: shellscape Date: Sat, 8 Jun 2019 09:32:11 -0400 Subject: [PATCH 3/3] feat: forward unhandled emitter events to websocket --- lib/index.js | 12 ++++++++++++ lib/routes.js | 24 ++++++++++-------------- recipes/watch-static-content.md | 4 +++- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/index.js b/lib/index.js index 8901aed..13f8363 100644 --- a/lib/index.js +++ b/lib/index.js @@ -135,6 +135,18 @@ class WebpackPluginServe extends EventEmitter { return result; } + // #138. handle emitted events that don't have a listener registered so they can be sent via WebSocket + emit(eventName, ...args) { + const listeners = this.eventNames(); + + if (listeners.includes(eventName)) { + super.emit(eventName, ...args); + } else { + const [data] = args; + super.emit('unhandled', { eventName, data }); + } + } + hook(compiler) { const { done, invalid, watchClose, watchRun } = compiler.hooks; diff --git a/lib/routes.js b/lib/routes.js index b30eafb..6d78eda 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -25,7 +25,7 @@ const statsOptions = { const setupRoutes = function setupRoutes() { const { app, options } = this; - const events = ['build', 'done', 'invalid', 'progress', 'reload']; + const events = ['build', 'done', 'invalid', 'progress']; const connect = async (ctx) => { if (ctx.ws) { const socket = await ctx.ws(); @@ -35,13 +35,6 @@ const setupRoutes = function setupRoutes() { } socket.send(data); }; - - const reload = (data) => { - if (options.hmr || options.liveReload) { - const action = options.liveReload ? 'reload' : 'replace'; - send(prep({ action, data })); - } - }; socket.build = (compilerName = '', { wpsId }) => { send(prep({ action: 'build', data: { compilerName, wpsId } })); @@ -78,12 +71,15 @@ const setupRoutes = function setupRoutes() { } } - reload({ hash, wpsId }) + if (options.hmr || options.liveReload) { + const action = options.liveReload ? 'reload' : 'replace'; + send(prep({ action, data: { hash, wpsId } })); + } }; socket.invalid = (filePath = '', compiler) => { const context = compiler.context || compiler.options.context || process.cwd(); - const fileName = filePath.replace && filePath.replace(context, '') || filePath; + const fileName = (filePath.replace && filePath.replace(context, '')) || filePath; const { wpsId } = compiler; send(prep({ action: 'invalid', data: { fileName, wpsId } })); @@ -92,10 +88,6 @@ const setupRoutes = function setupRoutes() { socket.progress = (data) => { send(prep({ action: 'progress', data })); }; - - socket.reload = (data) => { - reload(data); - }; for (const event of events) { this.on(event, socket[event]); @@ -105,6 +97,10 @@ const setupRoutes = function setupRoutes() { }); } + // #138. handle emitted events that don't have a listener registered, and forward the message + // onto the client via the socket + this.on('unhandled', ({ eventName, data }) => send(prep({ action: eventName, data }))); + send(prep({ action: 'connected' })); } }; diff --git a/recipes/watch-static-content.md b/recipes/watch-static-content.md index 78da016..b792ff7 100644 --- a/recipes/watch-static-content.md +++ b/recipes/watch-static-content.md @@ -69,7 +69,9 @@ serve.on('listening', () => { }); ``` -The important change there is `serve.emit('reload')`. We're including some sugar data there so that any listeners know where the event originated. That could be useful in an app that has multiple instruction points calling for reloads. +The important change there is `serve.emit('reload')`. The `reload` event isn't actually handled by the `WebpackPluginServe` instance, but the plugin _does_ forward on unhandled, emitted events to all connected `WebSocket`s. The `reload` event is already handled in the client scripts as part of the `liveReload` option, so we can utilize that `WebSocket` message to reload the page. Alternatively, you might choose to connect your own `WebSocket`, use a different action (such as `static-change`), and add more magic than a plain old `window.location.reload()`. + +We're also including some sugar data there in `{source: 'config' }` so that any listeners know where the event originated. That could be useful in an app that has multiple instruction points calling for reloads. ### 🍰 Dessert