bolt-cep icon indicating copy to clipboard operation
bolt-cep copied to clipboard

Invisible 'server' panel doesn't play well with the HMR feature

Open avibiton13 opened this issue 2 years ago • 3 comments

I've added another panel aside the main one, called 'server' which intended to expose my main panel to outside apps. My folder structure is as follows:

├── js
...
│   ├── lib
...
│   ├── main
...
│   ├── server
│   │   ├── index.html
│   │   └── index.ts
...

src/serve/index.ts code:

import { http } from "../lib/cep/node";

const port = 8088;
const server = http.createServer((req, res) => {
    console.log(req);
    if (req.url === '/ping') {
        res.setHeader('Content-Type', 'text/plain');
        res.end('pong');
    } else {
        res.setHeader('Content-Type', 'text/plain');
        res.statusCode = 400;
        res.end('METHOD_NOT_ALLOWED');
    }
});

server.listen(port, () => {
    console.log(`Server is running at http://localhost:${port}`);
    console.log(server.listening);
});

The problem: Each time I save any file HMR is triggered for all the files under src(and I do get that it's expected behavior) causing the listen function to re-run and raise the EADDRINUSE error.

My workaround: Adding the following line to the triggerHMR function that's inside vite.es.config.ts:

if (panel.name === "server") return;

triggerHMR looks like that right now:

  const triggerHMR = () => {
    // No built-in way to trigger Vite's HMR reload from outside the root folder
    // Workaround will read and save index.html file for each panel to triggger reload
    console.log("ExtendScript Change");
    cepConfig.panels.map((panel) => {
      if (panel.name === "server") return; // this is my addition
      const tmpPath = path.join(process.cwd(), "src", "js", panel.mainPath);
      if (fs.existsSync(tmpPath)) {
        const txt = fs.readFileSync(tmpPath, { encoding: "utf-8" });
        fs.writeFileSync(tmpPath, txt, { encoding: "utf-8" });
      }
    });
  };

So ultimately I'm losing the HMR feature for that panel, and each time I want it's code changes to take place I have to rebuild and restart After Effects.. Any ideas how to properly overcome that?

avibiton13 avatar Jul 11 '23 12:07 avibiton13

Just found a better solution:

  1. Canceling the changes to the triggerHMR function that I've mentioned above.
  2. Updated code for the src/js/server/index.ts file:
import { http } from "../lib/cep/node";
import { child_process } from "../lib/cep/node";

const port = 8088;
child_process.exec(`lsof -i :${port} | grep LISTEN | awk '{print $2}' | xargs kill`, (error, stdout, stderr) => {
    if (error) {
        console.error('Error occurred while killing the process:', error);
    } else if (stderr) {
        console.error('Error occurred while killing the process:', stderr);
    } else {
        const server = http.createServer((req, res) => {
            if (req.url === '/ping') {
                res.setHeader('Content-Type', 'text/plain');
                res.end('pong');
            } else {
                res.setHeader('Content-Type', 'text/plain');
                res.statusCode = 400;
                res.end('METHOD_NOT_ALLOWED');
            }
        });
        server.listen(port, () => {
            console.log(`Server is running at http://localhost:${port}`);
        });
    }
});

Please let me know what you think

avibiton13 avatar Jul 11 '23 12:07 avibiton13

I've just used Vite's vite:beforeUpdate to close the server:

server = startServer();
if (import.meta.hot) {
  import.meta.hot.on('vite:beforeUpdate', () => {
    server.close();
  })
}

Seems to work reliably!

vonstring avatar Jul 19 '23 21:07 vonstring

I've just used Vite's vite:beforeUpdate to close the server:

server = startServer();
if (import.meta.hot) {
  import.meta.hot.on('vite:beforeUpdate', () => {
    server.close();
  })
}

Seems to work reliably!

Just tried that, cannot get it to work.. do you use native node js http module as I do? and in addition - where do you place that if statement?

avibiton13 avatar Jul 24 '23 13:07 avibiton13