How to package express server inside electron app? - javascript

I am currently building electron app with vue-cli-electron-builder .
I have mysql local database and express server.
How do I bundle express server and Electron app?
I have used express server for fetching and storing data.
User login credentials are stored in mysql database, login form calls the express server.
User can register with new credentials which again calls the local express server and stores in local mysql database.
It would be perfect if I could package everything inside one app and still be able to access express server.
Running electron app and the separate express server works but I want to package both electron and express so that I can perform actions only with electron app.

In background.ts, you can import { fork } from 'child_process'.
And put server.js in /public/.
import { fork } from 'child_process'
const isDevelopment = process.env.NODE_ENV !== 'production'
const serverProcess = fork(isDevelopment
? path.resolve(__dirname, "../public/server.js")
: path.resolve(__dirname, "server.js"))
try {
serverProcess.stdout!.on("data", console.log)
serverProcess.stderr!.on("data", console.error)
} catch(e) {}
I have done it with vue-cli-electron-builder at some time as well, but it conflicts with Reveal.js, so I did it manually.
background.ts
server.js
However, regarding MySQL, you shouldn't put .env or credentials in Electron, as people can reverse engineer it, needing a separate web server.

Related

Nuxt & Express server not getting api requests in production /dist

I have a Nuxt app running successfully on my local server and all API requests are successfully running from the same server (using the serverMiddleware property in nuxt.config.js). When I run a yarn generate, the path to the API server is lost and no data is loaded. Below are a few screenshots.
Loads data successfully from the API.
Unable to find API
Here is an example of an api call in project_dir api/index.js file
const express = require("express");
const passport = require("passport");
const allRoutes = require("../api/routes/routes");
const guestRoutes = require("../api/routes/guest");
const fileUpload = require("express-fileupload");
const path = require("path");
// Create express instance
const app = express();
// Init body-parser options (inbuilt with express)
app.use(express.json());
app.use(fileUpload());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "../", "dist")));
/**
* -------------- PASSPORT AUTHENTICATION ----------------
*/
// Need to require the entire Passport config module so index.js knows about it
require("./config/passport-jwt");
// Initialize Passport
app.use(passport.initialize());
/**
* -------------- ROUTES ----------------
*/
// Imports all of the routes from ./routes/index.js
app.use(guestRoutes);
app.use(passport.authenticate("jwt", { session: false }), allRoutes);
console.log("express");
console.log(path.join(__dirname, "../", "dist"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../", "dist", "index.html"));
});
// Export express app
module.exports = app;
I don't know why I'm not able to get data from the API routes which I'm running on the same server.
Here is an in-depth answer on how to run an Express server alongside Nuxt: https://stackoverflow.com/a/72102209/8816585
First thing to know, is that you cannot have a Node.js server with yarn generate because it's using target: 'static' and as you can guess, when something is static, it doesn't need a Node.js server to be served to the end-user (only the html + css + js static files are hosted on a CDN or alike).
This mode is meant to host the code on Netlify, Vercel or alike, with no Node.js server available there.
Why is it working locally? Because you do have a Webpack dev server running (with a Node.js server so) for debugging purposes like HMR etc...
TDLR: this is normal (works as intended so far). More info on the given link above on how to make it work.
After much research and debugging I came up with a new idea.
Instead of running npm run start or yarn start containing script "nuxt start" inside the package.json file. I added a new script with the name "express-start": "cross-env NODE_ENV=production node api/index.js". Which runs the express server and nuxt static files.
I'm currently creating a template to make it easier for those who'll face this challenge.
Link to a boilerplate I created after solving the issue.
ExpressJs & NuxtJs Boilerplate

Rendering react with node.js in development

I am (very) new to node.js and I am trying to get a development environment started with React.
const express = require('express')
const mongoose = require('mongoose')
const app = express()
// this displays the index.html file
app.use(express.static(__dirname + '/public'));
// trying to see the app.js
app.get('/', (req, res) => {
res.render('app')
})
app.listen(process.env.PORT || 5000);
Right now I am simply trying to be able to view my app.js when I run nodemon. But right now it is only showing the index.html file in the public folder. and when I run npm start it renders both the index.html and the app.js.
I am 100% doing something wrong and am not in my element here. Any help/advice would be appreciated.
My full repo is here for viewing here
Thank you in advance.
Your code is simply serving a static HTML file located in the public directory everytime the user make a GET request to the root (in your case, localhost:5000). It is not interacting with React yet.
Usually when starting a project with React (frontend) and Node (backend), you would create them as separate projects, in separate repositories.
So you could create a React application using a bootstrap such as create-react-app running on PORT 3000 and in another terminal tab, start your NodeJS application in PORT 5000 like in your example. Then, you can call your backend endpoint from your frontend React application, by referencing http://localhost:5000
By doing this, your backend code don't need to serve static files anymore, it can return data such as JSON and make connections to a database for example.
Since your question is not specific enough, you could be talking about server side render. In server side render apps using Node and React, you have a frontend built with React and a Node server that will return the same React code as a string, using the react-dom/server package to help. This is more complex, but basically you will have the same React code on the client AND on the server. There are performance benefits, because the user can see some content rendered right when he enters the page, without having to wait the React bundle (javascript file) to load. If you want to know more about creating a server side render app with React and Node, there is a nice digital ocean tutorial here
If you want to connect your react js project to the node js
In Development
you simply run their server and start it
In Production
You can use sendFile function coming from express.js to run the frontend
https://dev.to/loujaybee/using-create-react-app-with-express

Can't run puppeteer in react app, Module not found: Can't resolve 'ws' when compiling

I was wondering if it was possible to run puppeteer in my react app. Whenever I try to run puppeteer in my react app I get "Module not found: Can't resolve 'ws'". I've tried installing ws but will still get the same error.
Simple answer : You can't run puppeteer in react app.
React is a client side framework. which means it runs in browser.
While puppeteer is a NodeJS lib, it needs Node.js and runs on server side.
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.
Expanding on the above answer. You cannot directly run Puppeteer on a react app. React app is a frontend framework and you would need Puppeteer to run on a node js, server. It's a simple "fix" and I wanted to explain it a little more than the answer above does.
The steps to get them to work together would be.
Setup an express server. You can create an express server like so:
Separate directory reactServer. Npm init directory and npm i express.
In your express server you allocate a path
const express = require('express')
const app = express()
const port = 5000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.get('/my-react-path', (req, res) => {
// run any scripts you need here
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Then your react app will interact with your server like so:
localhost:5000/my-react-path
In the my-react-path you can create a function that fires up puppeteer and does all the things you want on the server side and it can return whatever results to React. The above example is just to get you started it doesn't have anything related to puppeteer.

proxy not working for create-react-app in production

I am working with reactjs(create-react-app) to create a dashboard application, In my application i am calling multiple host (for that I have configured multiple proxies in package.json to avoid CORS).
ex- www.app.demo1.com, www.app.demo2.com, www.app.demo3.com...
"proxy": {
"/demo1/api/":{
"target":"www.app.demo1.com"
},
"/demo2/api/":{
"target":"www.app.demo2.com"
},
"/demo3/api/":{
"target":"www.app.demo3.com"
}
}
in application i am calling like-
try{
const host1 = process.env.NODE_ENV === 'production'?
'www.app.demo1.com/demo1/api': '/demo1/api/';
const host2 = process.env.NODE_ENV === 'production'?
'www.app.demo2.com/demo2/api': '/demo2/api/';
const host3 = process.env.NODE_ENV === 'production'?
'www.app.demo3.com/demo3/api': '/demo3/api/';
const resp1 = axios.get(host1)
const resp2 = axios.get(host2)
const resp3 = axios.get(host3)
}catch(){}
in development: when making request to /demo1/api/ it is being proxied to
www.app.demo1.com/demo1/api and i am getting the response. but
in production: I have deployed the application on github pages, although I am getting the below error,
enter image description here
Can anybody help..
Proxies are for development purposes only, and they are handled by webpack-dev-server. On production you need to make the calls to the actual host.
This is created because usually, on development, react is served by a standalone server meant just for that (hence, webpack-dev-server). On production, usually there is a backend (node? ruby? php?) that serves the pages and every call made is going to be to some endpoint with the same hostname.
Example:
In your development environment you have a node server running on port 3001 and your react code running on port 3000. When react fetches /api/user, you actually want http://localhost:3001/api/user, which points to your node server.
In your production environment, you have a server (nginx, maybe?) that forwards all /api calls to your node process, and for everything else it serves your react main index.html file (so you can use react-router, for example). In this case, whenever you request /api/user, this is going to be handled by your web server and routed properly.

Getting an express app working online

I am new to expressjs and am trying to get my express application (done with the express generator) working on my website, I currently uploaded the directory which is is contained in like so..
http://www.example.com/express-app-here
so I could see it working online. However, when I navigate to where the App is, I seem to only get the directory structure, and express isn't routing me to the appropriate place like it is when I go to localhost:3000.
I take it this has something to do with the fact that express isn't executing my application? Locally,
npm start
needs to be run on the console in order to get it to run, is there some kind of log I need to execute this command in? Or something I need to change in the app.js or /bin directory?
As it was said in the comments, you need to have nodejs installed on your server. It's not as simple as just copying the node app directory over to the server.
You will have to install node and npm on the server, and then run your app from the server, probably using npm start like you were doing on your local machine.
From there, you will want to go into your app code and make sure a route exists for /express-app-here unless you want www.example.com:3000 to take you directly to the express app.
Basically do it like this:`
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
var port = process.env.PORT || config.webServer.port || 3000;
server.listen(port, function () {
console.log('server running');
console.log(port);
console.log(server);
});
exports.module = exports = app;
save it app.js
Go to path via cmd. Now run:-
1)npm install express
2)npm install http
3)node app.js
Will be enough to run express server

Categories