mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-12-01 02:21:39 +00:00
feat(core): add server:watch script with automatic restart on file changes (#3920)
## Description
This PR adds a new `server:watch` script that runs MagicMirror² in
server-only mode with automatic restart and browser reload capabilities.
Particularly helpful for:
- **Developers** who need to see changes immediately without manual
restarts.
- **Users setting up their mirror** who make many changes to `config.js`
or `custom.css` and need quick feedback.
### What it does
When you run `npm run server:watch`, the watcher monitors files you
specify in `config.watchTargets`. Whenever a monitored file changes:
1. The server automatically restarts
2. Waits for the port to become available
3. Sends a reload notification to all connected browsers via Socket.io
4. Browsers automatically refresh to show the changes
This creates a seamless development experience where you can edit code,
save, and see the results within seconds.
### Implementation highlights
**Zero dependencies:** Uses only Node.js built-ins (`fs.watch`,
`child_process.spawn`, `net`, `http`) - no nodemon or external watchers
needed.
**Smart file watching:** Monitors parent directories instead of files
directly to handle atomic writes from modern editors (VSCode, etc.) that
create temporary files during save operations.
**Port management:** Waits for the old server instance to fully release
the port before starting a new one, preventing "port already in use"
errors.
### Configuration
Users explicitly define which files to monitor in their `config.js`:
```js
let config = {
watchTargets: [
"config/config.js",
"css/custom.css",
"modules/MMM-MyModule/MMM-MyModule.js",
"modules/MMM-MyModule/node_helper.js"
],
// ... rest of config
};
```
This explicit approach keeps the implementation simple (~260 lines)
while giving users full control over what triggers restarts. If
`watchTargets` is empty or undefined, the watcher starts but monitors
nothing, logging a clear warning message.
---
**Note:** This PR description has been updated to reflect the final
implementation. During the review process, we refined the approach
multiple times based on feedback.
---------
Co-authored-by: Jboucly <contact@jboucly.fr>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
This commit is contained in:
@@ -111,6 +111,13 @@ function Server (config) {
|
||||
|
||||
app.get("/", (req, res) => getHtml(req, res));
|
||||
|
||||
// Reload endpoint for watch mode - triggers browser reload
|
||||
app.get("/reload", (req, res) => {
|
||||
Log.info("Reload request received, notifying all clients");
|
||||
io.emit("RELOAD");
|
||||
res.status(200).send("OK");
|
||||
});
|
||||
|
||||
server.on("listening", () => {
|
||||
resolve({
|
||||
app,
|
||||
|
||||
Reference in New Issue
Block a user