3

In case the lenght of the question might be scary, the summary of the question is how to interact with a front end app from a node server. Puppeteer usage should come along with that request solved I believe. Question is large because I explained all my failed attempts to achieve backend code (puppeteer) work in the browser. Apart from building and running the repo that although its easy right following the instructions might take a some time, I believe the question should be feasable for a javascript/node regular programmer. There it goes, thanks for reading.

I cloned, built and ran imgui-js repository succesfully. I want to use it along with puppeteer for a small app. All the npm commands inside and stuff tried are inside the mentioned imgui-js project.
I tried:

1.- Run the node example from the project: With npm run-script start-example-node. This runs the example/index.js script, but nothing is drawn as we are not in the browser and the window is undefined. Can be checked debugging in the main.ts:

if (typeof(window) !== "undefined") {
    window.requestAnimationFrame(done ? _done : _loop);
} 

So I do not understand the purpose of this example in the repo. Edit: Seems it can be to have the client-server comunication done, but I do not now how to do this.

2.- Puppeteer browserify: I followed the browserify hello world. Just a summary of the steps:

  1. npm install -g browserify
  2. npm i puppeteer
  3. Go to the build folder to generate de bundle.js for my const puppeteer = require('puppeteer'); script, so cd example, cd build, browserify myScript.js -o bundle.js
  4. Add <script src="./build/bundle.js"></script> to the example/index.html.

I obtain this error:

Uncaught TypeError: System.register is not a function
    at Object.96.puppeteer (bundle.js:19470:8)
    at o (bundle.js:1:265)
    at r (bundle.js:1:431)
    at bundle.js:1:460

I also tried browserifying main.js along with my script: browserify main.js myScript.js -o bundle.js. Same error.

3.- Try to setup puppeter with the rollup module bundler: following this resource among others. So doing:

npm install --save-dev rollup tape-modern puppeteer
npm install --save-dev rollup-plugin-node-resolve
npm install --save-dev rollup-plugin-commonjs
npm install --save-dev sirv tape-browser-color

And tried to add that the the imgui-js rollup.config.js configuration file. Think its not working because all the server setup at the npm start and so on is not performed with rollup.

4.- Puppeteer-web: Following the steps of this resource I tried to run puppeteer in the browser.

  1. npm i puppeteer-web
  2. Code in the client and the server:

Client:

<script src="https://unpkg.com/puppeteer-web"></script>
<script>
  const browser = await puppeteer.connect({
    browserWSEndpoint: `ws://0.0.0.0:8080`, // <-- connect to a server running somewhere
    ignoreHTTPSErrors: true
  });

  const pagesCount = (await browser.pages()).length;
  const browserWSEndpoint = await browser.wsEndpoint();
  console.log({ browserWSEndpoint, pagesCount });
</script>

Server (server.js script):

const httpProxy = require("http-proxy");
const host = "0.0.0.0";
const port = 8080;

async function createServer(WSEndPoint, host, port) {
  await httpProxy
    .createServer({
      target: WSEndPoint, // where we are connecting
      ws: true,
      localAddress: host // where to bind the proxy
    })
    .listen(port); // which port the proxy should listen to
  return `ws://${host}:${port}`; // ie: ws://123.123.123.123:8080
}

const puppeteer = require("puppeteer");

puppeteer.launch().then(async browser=>{
  const pagesCount = (await browser.pages()).length; // just to make sure we have the same stuff on both place
  const browserWSEndpoint = await browser.wsEndpoint();
  const customWSEndpoint = await createServer(browserWSEndpoint, host, port); // create the server here
  console.log({ browserWSEndpoint, customWSEndpoint, pagesCount });
})
  1. Run server script: node server.js. Server seems properly created. Terminal log:

    browserWSEndpoint: 'ws://127.0.0.1:57640/devtools/browser/58dda865- b26e-4696-a057-25158dbc4093',
    customWSEndpoint: 'ws://0.0.0.0:8080',
    pagesCount: 1

  2. npm start (from new terminal to assure the created server does not terminate)

I obtain the error in the client:

WebSocket connection to 'ws://0.0.0.0:8080/' failed: 
(anonymous) @ puppeteer-web:13354

I just want to use puppeteer with this front end library together in my app, fetching data with puppeteer to display it the UI and provide the user input back to puppeteer.

My ideal solution would be number 1, where I would be able to use any npm package apart from puppeteer and communicate from the backend(node server) to the client (imgui user interface) back and forth.

Thanks for any help.

EDIT: I more less achieved it with the node server solution server which is my desired scenario, with expressjs and nodemon, running a different server in the application and communicationg with the app. Now I would find more valuable any help on:

1.- The browserifying solution and or insight about why my attempts with this approach failed.
2.- The solution that keeps everything in the one same server, that would be the server that in the repo serves the html to the browser with "start-example-html": "http-server -c-1 -o example/index.html". Dont know if that is possible. Its because I would not lose the life loading etc if I serve both things with my expressjs server added by myself. Kind of what Create React App does with Proxying API Requests
3.- As suggested in the comments, guidance or solution to make the server code render a window through node with the imgui output (npm start-example-node) of course would be a valid answer to the question.

Seems not quite correct to change the question conditions during the bounty with a bit of a broad new scenario, but now that conditions has changed so I try to make the most of the investment and the research already done in the topic, also due to my lack of expertise in the wev-dev module bundling configuration area, so bounty may be granted for the most valuable advice in any of the two topics mentioned above. Thanks for your understanding.

rustyBucketBay
  • 4,320
  • 3
  • 17
  • 47
  • 1
    I'm surprised no one tried to tackle this question yet... Speaking of questions, I have a few to help me understand the situation better and provide help if I can: What is it exactly you try to achieve? From what I can see from their CodePen demo, it seems like a simple box with text fields, buttons and sliders. Is it absolutely mandatory for you to use imgui-js or is it because you're more familiar with C++/C#/C? Why would you want to use puppeteer for? Why would the "back-end" do in this scenario? – Gaëtan Boyals Feb 19 '22 at 14:27
  • Thanks a lot for your comment! I am bit surprised also. Does not seem that difficult, however to tackle it the repo must be built and run that might take a while. `What is it exactly you try to achieve?` -> run server code is this concrete repo. `Is it absolutely mandatory for you to use imgui-js or is it because you're more familiar with C++/C#/C?` -> I am, but not for that reason. It is just because I tried to do it and I did not achieve it, so I just become obsessed with the problem. Its just due to stubbornness. – rustyBucketBay Feb 19 '22 at 19:08
  • `Why would you want to use puppeteer for? Why would the "back-end" do in this scenario?` -> fetch some info from a web, gather some user input, and submit that info back to puppeteer to make some stuff automatically – rustyBucketBay Feb 19 '22 at 19:08
  • I more less achieved it, so please read the edited answer if you are considering exploring the topic :) – rustyBucketBay Feb 19 '22 at 19:12
  • 1
    Ha, love the honesty of the replies! I'll look into the edited answer and see if I can come up with something. – Gaëtan Boyals Feb 19 '22 at 19:54
  • 1
    The server code in the repo works fine, it's just not supposed to render anything since there is no window object defined in Node. The purpose of the example is to show that the lib can run server side. If you want to get an output from Node, you should edit main.js code and render imgui inside node-canvas or similar. – Jean-Baptiste Martin Feb 19 '22 at 20:46
  • that is a great insight, thanks a lot. I was not getting the point of that. Also was not aware of node canvas. Seems a bit tough to build and compile. However it doesnt seem trivial to bind the imgui output to a node window. I gave a look to nodeGui, reactNodeGui and even I know how to render the window, I think I miss the step that to link the imgui render output to the window, so that would be a valid answer tothis question – rustyBucketBay Feb 19 '22 at 22:46
  • nodeGui is for building desktop apps. Is that what you are trying to do? If so go instead for Electron, it will be easier. Electron provides a full Node.js core and a Chromium DOM that communicate together, no 3rd-party involved and no puppeteer needed. – Jean-Baptiste Martin Feb 20 '22 at 10:30
  • `nodeGui is for building desktop apps. Is that what you are trying to do?` -> i am trying to run backend code (puppeteer is an example of code that cannot run in the browser) with this library. No matter if its a desktop or a web app. I know that there are other better alternatives, but the question is to make that with this library (imgui-js). By run backend code I mean that I can comunicate backend and imgui-js – rustyBucketBay Feb 20 '22 at 14:25

0 Answers0