electron-packager win32 don't open window - node.js

I have tried to build a very simple app with Electron, Node and AngularJS. The app is working well till I pack it. After packing, it doesn't show the window.
The ideea was to run a NodeJS process on localhost:5000, then to load the url in ElectronJS main window. When I double-click on .exe file, the process is starting at localhost:5000 and it's working in the browser only, but the Electron window is not shown.
Also, It crash when trying to open with npm run start / npm start
"Windows Script Host. Error: Syntax error. Code: 800A03EA. Source: Microsoft JScript compilation error."
package.json
"scripts": {
"start": "electron ."
}
server.js
'use strict';
const
express = require('express'),
app = express();
app.set('port', (5000));
app.use(express.static('app'));
app.use(express.static('dist'));
app.use(express.static('node_modules'));
app.get("*", (req,res)=>{
res.sendFile(__dirname+"/app/index.html");
});
app.listen(app.get('port'), function() {
console.log("Node server is running at localhost:" + app.get('port'));
});
electron.js
'use strict';
const
electron = require('electron'),
server = require('./server.js'),
{app, BrowserWindow} = electron;
app.on('ready', () => {
var win = new BrowserWindow({
show: false,
width: 800,
height: 600
});
win.loadURL("http://localhost:5000/");
win.on('ready-to-show', function() {
win.show();
win.focus();
});
win.on('closed', () => {
win = null
});
});
I can find the process in task manager.
NodeJS is running on localhost:5000. I can see it in the browser.

I can't see any issues with your code. But I did find a related issue which might be impacting you: https://github.com/electron/electron/issues/7779
Can you start electron in debug mode and check if the ready-to-show event fired?

I discovered that is a versioning incompatibility. At least, in my case was.
The following combination fixed my problem:
"electron": "^3.0.4" with "electron-packager": "^12.2.0"

Related

Prevent Nodemon to restart some specific code

I'm using nodemon in my nodejs project because I want whenever I made any changes it will restart automatically everything works fine but now problem is I want to use a lib
which include puppeteer lib whenever I made any changes nodemon close the chromium browser and re-open it which take some time. This is making me slow in development. Is there any way I can stop this behaviour.
Here is my code.
const express = require("express");
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Client } = require("whatsapp-web.js");
const client = new Client({ puppeteer: { headless: false } });
client.initialize();
console.log("changes 7");
server.listen(3000, () => {
console.log("listening on *:3000");
});
Whenever I made any changes it restart everything. I don't want to restart the client every time.
I don't know about nodemon, but if you can edit the library, you can re-use an existent browser.
Try, from node shell:
(await require('puppeteer').launch()).wsEndpoint()
this return a connection string that you can reuse.
And, then, you can connect with the created instace with connect api
Edit: your library allows ws socket! :-)
const client = new Client({
puppeteer: {
browserWSEndpoint: `ws://localhost:3000`
}
});
create nodemon.json in your project directory
nodemon will automatically look for this file and use it if exist
and write in nodemon.json
{
//list of directory you want to watch
"watch": ["./","server","someOtherDir"],
"ext": "js,ts,json", //file extension to watch
"ignore": ["ignoreThisDir","someDir/*.js"], //specify files or directory to ignore
// specify entry of the project
"exec" : "node app.js"
//another example for exec "exec": "ts-node --project tsconfig.server.json server/app.ts"
}

Deploying VueJS app - Back end (ExpressJS) Not Responding

This is my first time deploying a VueJS app. It is full stack, back end is Express/MySQL. All running fine in developer mode. My dev platform is Windows 10, VS Code.
I am currently trying to preview the app on my dev PC using local webserver.
To that end, I built Vue app to server/public. The static site then runs fine, but I can't seem to get the Express back end to respond, either from the app or from browser accessing the api directly. I followed a model from Brad Traversy tutorial, here is what vue.config.js looks like:
const path = require('path');
module.exports = {
outputDir: path.resolve(__dirname, './server/public'),
devServer: {
disableHostCheck: true,
proxy: {
'/api': {
target: 'http://localhost:5000'
}
}
},
transpileDependencies: ['vuetify'],
pluginOptions: {
i18n: {
locale: 'en',
fallbackLocale: 'en',
localeDir: 'locales',
enableInSFC: false,
},
},
};
Here is the index.js for Express/back end. I commented out the NODE_ENV test because I haven't yet figured out how to set it properly. This should just hardwire the code to run in production mode. __dirname points to the server directory, which contains the Express code and other server stuff.
// Create express app
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
//Create Express App
const app = express();
// Add Middleware
app.use(bodyParser.json());
app.use(cors());
//
const water = require('./routes/api/water');
const waterlog = require('./routes/api/waterlog');
// Direct /api
app.use('/api/water', water);
app.use('/api/waterlog', waterlog);
// Handle production
// if (process.env.NODE_ENV === 'production') {
// Static folder
app.use(express.static(__dirname + '/public/'));
// Handle SPA
app.get(/.*/, (req, res) => res.sendFile(__dirname + '/public/index.html'));
// }
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`CORS-EnabledServer started on port ${port}`));
I use (from npm serve) this to start the Vue app:
serve -s server/public
What am I missing? Feels very close but no cigar yet...
serve is just a simple, static HTTP server. It won't run your backend.
Your production build puts your front-end assets into your Express app's statically served directory so all you should need to do after building the front-end is start your server
# Build your front-end
npm run build
# Start your Express server, assuming this is configured in package.json
NODE_ENV=production npm start
Now open http://localhost:5000/ in your browser
See also https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production

How to run Selenium-Webdriver on Heroku with node.js (Firefox or Chrome)

I want to use Selenium on Heroku with Firefox or another browser that is able to display videos. Unfortunately, PhantomJS doesn't work because the browser can't play video.
I already tried it with firefox by using these buildpacks:
https://github.com/buitron/firefox-buildpack
https://github.com/buitron/geckodriver-buildpack
And with chrome by using these buildpacks:
https://github.com/heroku/heroku-buildpack-chromedriver
https://github.com/heroku/heroku-buildpack-google-chrome
But I always get this in the heroku-logs:
2019-09-20T15:04:47.000000+00:00 app[api]: Build succeeded
2019-09-20T15:04:49.118915+00:00 app[web.1]: Error: Server terminated early with status 2
2019-09-20T15:04:49.118934+00:00 app[web.1]: at earlyTermination.catch.e (/app/node_modules/selenium-webdriver/remote/index.js:251:52)
2019-09-20T15:04:49.118936+00:00 app[web.1]: at process._tickCallback (internal/process/next_tick.js:68:7)
Is there a way to use selenium on heroku with a browser that can display video formats, like videos on youtube?
I haven't found a solution that works for me yet.
UPDATE
If I try this answser the same error will be displayed:
const chrome = require('selenium-webdriver/chrome');
let options = new chrome.Options();
options.addArguments('--headless');
options.addArguments('--disable-gpu');
options.addArguments('--no-sandbox');
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
driver.get('http://www.google.com').catch(err => console.log(err));
I tried this and it worked.
Note: I am using React, Express, and Selenium with chrome
Step 1: Create a new Heroku app.
Step 2: From your terminal, login to heroku using heroku login
step 3: Once you're logged in, cd to your project directory and set its remote to your heroku app. heroku git:remote -a YOUR-HEROKU-APP-NAME
step 4: Run all the following commands in your terminal
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-chromedriver
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-google-chrome
heroku config:set CHROME_DRIVER_PATH=/app/.chromedriver/bin/chromedriver
heroku config:set CHROME_BINARY_PATH=/app/.apt/opt/google/chrome/chrome
step 5: Login to heroku from your browser and navigate to your app. Go to settings and under buildpacks, add heroku/nodejs
step 6: This is how my index.js looks like. Note: my express entry point is inside root-dir/server/index.js and my react files are inside root-dir/client/
const express = require('express');
const app = express();
const path = require('path');
// Serve static files from the React app.
app.use(express.static(path.join(__dirname, '..', 'client/build')));
app.get('/api', async (req, res) => {
const webdriver = require('selenium-webdriver');
require('chromedriver');
const chrome = require('selenium-webdriver/chrome');
let options = new chrome.Options();
options.setChromeBinaryPath(process.env.CHROME_BINARY_PATH);
let serviceBuilder = new chrome.ServiceBuilder(process.env.CHROME_DRIVER_PATH);
//Don't forget to add these for heroku
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.setChromeService(serviceBuilder)
.build();
await driver.get('http://www.google.com');
res.send(await driver.getTitle());
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '..', 'client/build/index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`listening to port ${port} now...`);
});
step 7 (if you are using React): Now inside your package.json in root-dir/, add this
"scripts": {
...
"heroku-postbuild": "cd client && npm install && npm run build"
}
step 8 (if you are using react): inside your package.json in root-dir/client/ (i.e: package.json for react app), add the following line:
"proxy": "http://localhost:5000/",
step 8: (if you're using react): inside root-dir/client/src/, create a new file called setupProxy.js and paste the following code:
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(proxy('/api', { target: `http://localhost:${process.env.PORT || 5000}/`}));
};
step 9: Now, you are ready for deployment. Make sure you have the following packages installed: express, selenium-webdriver, and chromedriver
step 10: now push it to heroku
git add .
git commit -m "my app"
git push heroku master
My option, maybe it could help :
const screen = {
width: 1920,
height: 1080
};
let options = new chrome.Options();
//Below arguments are critical for Heroku deployment
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
options.windowSize(screen);
I think window size is mandatory, else you are emulating an unbounded window...

Use Nuxt programmatically without builder

I am using nuxt programmatically inside express with nuxt.render middleware like below
const { Nuxt, Builder } = require('nuxt')
const app = require('express')()
const api = require('../api')
app.use('/api', api)
let config = require('../nuxt.config.js')
config.dev = !(process.env.NODE_ENV === 'production')
// Init Nuxt.js
const nuxt = new Nuxt(config)
app.use(nuxt.render)
async function start() {
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// Listen the server
app.listen(port, host)
console.log('Server listening on ' + host + ':' + port)
}
start()
When I am developing the server api routes and make some changes to the server side api files and restart the server, the whole nuxt project builds everytime which takes too much time. This is inconvenient as there were no changes in the nuxt files, only changes in the api route files.
So after building once, I comment out the following lines:
if (config.dev) {
// const builder = new Builder(nuxt)
// await builder.build()
}
I then restart the server which of course does not start the nuxt builder. But then I am now not able to access nuxt on browser. The server api routes work but the nuxt page routes just show "Nuxt loading…" screen.
How can I use nuxt app in development mode without building it everytime?
It might be a valid use case, sometimes one doesn't want to use two servers for a very small api/ui pair. What I would suggest is also to have a detached mode which works through nuxt/proxy and you could run it whenever you are doing dev work. In detached mode your nuxt works separately and api runs also separately and nuxt imitates above setup via `nuxt/proxy. It's very easy to setup via adding smth like this in nuxt config
modules: [
['#nuxtjs/proxy', { "/api/": { target: 'http://localhost:888/api'} }]
]
In prod you could run as before.
You can use build.parallel, build.cache, and build.hardSource. This will dramatically speed up your build times after the initial build.
I do not recommend this for production builds though. This is how I have it in my code:
nuxt.config.js:
const isDev = process.env.NODE_ENV === "development";
module.exports = {
// ...
build: {
parallel: isDev,
cache: isDev,
hardSource: isDev
},
// ...
};
And in the package.json I set the NODE_ENV to production for the build script:
"scripts": {
"build": "NODE_ENV=production nuxt build"
}
P.S.: You might also need to set build.publicPath for the dev builds.

Using browser-sync with node.js app

I have an existing node app. My Node directory structure is setup like this:
./
node_modules/
src/
views/
index.html
...
server.js
test/
gulpfile.js
package.json
I can successfully start my app my running node ./src/server.js from the root shown above. Once started, I can visit "http://localhost:3000" in the browser and see the contents of index.html like I am expecting.
I want to speed up my development and I recently learned about browsersync. In an attempt to include it in my gulp process, I have the following:
var browserSync = require('browser-sync').create();
browserSync.init({
server: {
baseDir: './src/',
server: './src/server.js'
}
});
When I run gulp, I see the following in the command-line:
BS] Access URLs:
--------------------------------------
Local: http://localhost:3000
External: http://[ip address]:3000
--------------------------------------
UI: http://localhost:3001
UI External: http://[ip address]:3001
--------------------------------------
My browser is then opened and it attempts to load http://localhost:3000. At this point, I see the following error in the browser window:
Cannot GET /
What am I doing wrong? I can successfully visit http://localhost:3000 if I start my app using node ./src/server.js, however, its like its not running with BrowserSync. What am I doing wrong?
You already have a node server so i think what you need is Proxy.
And i would also suggest you to use nodemon for going one step ahead in your speed up development thing. It will automatically restart your node development server in case of any changes. So a sample gulpfile in your case(with nodemon) might look like
var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var nodemon = require('gulp-nodemon');
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:3700", // port of node server
});
});
gulp.task('default', ['browser-sync'], function () {
gulp.watch(["./src/views/*.html"], reload);
});
gulp.task('nodemon', function (cb) {
var callbackCalled = false;
return nodemon({script: './src/server.js'}).on('start', function () {
if (!callbackCalled) {
callbackCalled = true;
cb();
}
});
});
~
Why do you want to use the built-in server if you have your own in ./src/server.js ?
Check this, What server in browsersync does is create a static server for basic HTML/JS/CSS websites, so you might need to use the proxy feature as shown here.
This means that you need to run your server as normally and wrap it up in the proxy.
Using the express generator default folder structure with the start script in bin\www, and using the ejs template, this is how i modified my gulpfile.js :
var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var nodemon = require('gulp-nodemon');
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:8000", // port of node server
});
});
gulp.task('default', ['browser-sync'], function () {
gulp.watch(["./views/*.ejs"], reload);
});
gulp.task('nodemon', function (cb) {
var callbackCalled = false;
return nodemon({
script: './bin/www',
env: {
PORT: 8000
}}).on('start', function () {
if (!callbackCalled) {
callbackCalled = true;
cb();
}
});
});
Notice that am watching for any files that end in .ejs. I also got a problem when using nodemon with the port in use, so i added an env to pass the port as 8000,
env: { PORT: 8000 }
Since the tag grunt is missing from the question, here's a solution that works using only NPM (package.json):
"scripts": {
"start": "browser-sync start --serveStatic 'src' --serveStatic 'node_modules' --files 'src'"
}
Now all the <script> src attributes can be relative:
<script src="/stats-js/build/stats.min.js"></script>

Resources