I'd like to fire up a vue-cli dev server, then run a command from node once this build has completed.
Is there a way to run vue-cli-service serve from a node script so that I can receive a callback once the dev server is up and running?
vue-cli-service.js does not return the service promise (which would've allowed you to setup a completion callback), but you could make a copy of the script (25 lines) to do so:
my-vue-cli-service.js:
#!/usr/bin/env node
const semver = require('semver')
const { error } = require('#vue/cli-shared-utils')
const requiredVersion = require('#vue/cli-service/package.json').engines.node
if (!semver.satisfies(process.version, requiredVersion)) {
error(
`You are using Node ${process.version}, but vue-cli-service ` +
`requires Node ${requiredVersion}.\nPlease upgrade your Node version.`
)
process.exit(1)
}
const Service = require('#vue/cli-service')
const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
const rawArgv = process.argv.slice(2)
const args = require('minimist')(rawArgv)
const command = args._[0]
module.exports = () => // <--- add this line to return the service promise
service.run(command, args, rawArgv).catch(err => {
error(err)
process.exit(1)
})
Then, you could create another script that consumes this copy, adding a then callback to be invoked when the server started successfully:
my-service.js:
#!/usr/bin/env node
const service = require('./my-vue-cli-service')
service().then(result => {
if (result && result.server) { // <--- server started successfully if result.server exists
const {server, url} = result;
console.log('ready');
}
})
Be sure to update package.json to use the new script:
package.json:
{
"scripts": {
"serve": "./my-service.js serve"
}
}
Related
I've just finished my first vue+electron+flask project and I am having quite a hard time trying to package it. Everything is workig "perfectly" when using "npm run electron:serve" but when running "npm run electron:build" I do not get any error, but Flask is not launched at all. I do not really know how to fix the problem, my guess is that when building the dist folder the path to app.py is not correct, but I tried to fix it without luck.
Here is the background.js code:
'use strict'
import { app, protocol, BrowserWindow } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const isDevelopment = process.env.NODE_ENV !== 'production'
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
async function createWindow() {
// spawn flask app (https://medium.com/red-buffer/integrating-python-flask-backend-with-electron-nodejs-frontend-8ac621d13f72)
var python = require('child_process').spawn('py', ['../server/app.py']);
python.stdout.on('data', function (data) {
console.log("data: ", data.toString('utf8'));
});
python.stderr.on('data', (data) => {
console.log(`stderr: ${data}`); // when error
});
// Create the browser window.
const win = new BrowserWindow({
width: 1500,
height: 1200,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
}
createWindow()
})
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', (data) => {
if (data === 'graceful-exit') {
app.quit()
}
})
} else {
process.on('SIGTERM', () => {
app.quit()
})
}
}
The relevant part of the code calling app.py is the following:
async function createWindow() {
// spawn flask app (https://medium.com/red-buffer/integrating-python-flask-backend-with-electron-nodejs-frontend-8ac621d13f72)
var python = require('child_process').spawn('py', ['../server/app.py']);
python.stdout.on('data', function (data) {
console.log("data: ", data.toString('utf8'));
});
python.stderr.on('data', (data) => {
console.log(`stderr: ${data}`); // when error
});
// Create the browser window.
const win = new BrowserWindow({
width: 1500,
height: 1200,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
}
})
I tried to put 3 dots insted of 2 in the app.py path ['.../server/app.py] just in case when creating the dist folder I need this extra dot to find the app.py file, but this is not working either.
My folder structure is the follwing:
Vue-Electron
client
dist_electron
node_modules
public
src
assets
components
router
views
App.vue
background.js
main.js
other config files
server
data
env
app.py
requirements.txt
other python scripts imported to app.py
sqlite_portofolio.db
As this program will only be used by me in my personal pc, I did not want to bother using pyInstaller (I thought it would be easier to not package the python side, but if I am wrong please let me know). I would like to have a electron .exe file that I can just doble click to open the electron build and then spawn the Flask server.
Also, my feeling is that I am not killing the Flask server correctly when closing the app. I think Flask is still running when closing electron. What should I do to ensure Flask server is properly closed.
There is not a lot of information of those topics that I can follow. Any help will be aprreaciated.
I´m having the same problem. I followed the link to this article (https://medium.com/red-buffer/integrating-python-flask-backend-with-electron-nodejs-frontend-8ac621d13f72), and it has the answer about killing the python flask server. And if you follow everything the article says, it's supposed to run the backend when opening the electron.exe, but this is not happening here on my end.
EDIT: I found the error, you need to change the path on your spawn. I sugest you to run the electron.exe on the cmd so you can see the error on it, so you will see the path that spawn is trying to run.
it´s probably:
var python = require('child_process').spawn('py', ['../resources/app/server/app.py']);
you will need to acess the app.py through [resources/app] as spawn start at the base dir of the electron build.
PS: I used electron-packeger that´s why mine need to add resources/app, and I used pyinstaller on my backend
Hope it will help you.
I can't seem to find anything about running Svelte apps over https. I would like to run on https for both dev and prod. I am able to change the port with --port argument in the scripts in package.json, but obviously that doesn't change the protocol from http to https.
You need to create SSL certificates from somewhere(like ZeroSSL). If you already have got certificate.crt & private.key files, then edit your server.js file.
The original source codes of <sapper project directory>/src/server.js are:
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '#sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
polka() // You can also use Express
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.listen(PORT, err => {
if (err) console.log('error', err);
});
You can add & change some codes of this file(server.js) like this:
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '#sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
const { createServer } = require('https');
const { readFileSync } = require('fs');
const ssl_port = 443;
const options = {
// The path & file names could be different.
key: readFileSync('/home/ubuntu/ssl/private.key'),
cert: readFileSync('/home/ubuntu/ssl/certificate.crt')
};
const { handler } = polka()
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.get('*', (req, res) => {
res.end(`POLKA: Hello from ${req.pathname}`);
});
// Mount Polka to HTTPS server
createServer(options, handler).listen(ssl_port, _ => {
console.log(`> Running on https://localhost:${ssl_port}`);
});
The added codes are:
const { createServer } = require('https');
const { readFileSync } = require('fs');
const ssl_port = 443;
const options = {
// The path & file names could be different.
key: readFileSync('/home/ubuntu/ssl/private.key'),
cert: readFileSync('/home/ubuntu/ssl/certificate.crt')
};
The changed codes are:
const { handler } = polka()
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.get('*', (req, res) => {
res.end(`POLKA: Hello from ${req.pathname}`);
});
// Mount Polka to HTTPS server
createServer(options, handler).listen(ssl_port, _ => {
console.log(`> Running on https://localhost:${ssl_port}`);
});
And then you have to run your Svelte/Sapper apps with sudo because of the permission of port 443. (like this: sudo npm run dev or sudo npm run start)
After you run sudo npm run dev, you may see the messages:
$ sudo npm run dev
> TODO#0.0.1 dev /home/ubuntu/ensayar-sapper
> sapper dev
✔ server (2.1s)
✔ client (2.1s)
> Running on https://localhost:443
✔ service worker (42ms)
> Server is not listening on port 3000
You can ignore the message Server is not listening on port 3000.
This has noting to do with sapper. Just use the options of your server framework. Do you use express or polka? Follow their instructions!
It seems the only way to do it as of now is to run a reverse proxy (like nginx) in front of the Svelte/Sapper app.
E: sorry... this was the only answer for a while. Do I delete this or what?
Got a recent Requirement, where i need to do Test Automation of Backend Node js application using the spectron. I would like to know what are programming skills required to approach the same
Find the Spectron documentation at https://electronjs.org/spectron
Installation
npm install --save-dev spectron
Sample test file looks like this
const Application = require('spectron').Application
const assert = require('assert')
const electronPath = require('electron')
const path = require('path')
describe('Application launch', function () {
this.timeout(10000)
beforeEach(function () {
this.app = new Application({
path: electronPath,
args: [path.join(__dirname, '..')]
})
return this.app.start()
})
afterEach(function () {
if (this.app && this.app.isRunning()) {
return this.app.stop()
}
})
it('shows an initial window', function () {
return this.app.client.getWindowCount().then(function (count) {
assert.equal(count, 1)
})
})
})
Spectron can work with any test framework. I prefer using mocha.
Clone this project for more info https://github.com/electron/spectron
Please tell me in detail ..
I have an electron application and I have exe of that .. but want to automate using protractor framework.
Guide me in that .
You should try using Spectron
https://electronjs.org/spectron
Spectron is a testing tool for electron application. You can test it after packing into a exe file or straight away starting the test by mentioning the main.js
npm install --save-dev spectron
Install spectron via npm . Below example uses mocha for assertions.
To get up and running from your command line:
Install mocha locally as a dev dependency.
npm i mocha -D
create a spec file like below
const Application = require('spectron').Application
const assert = require('assert')
const electronPath = require('electron')
const path = require('path')
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
global.before(() => {
chai.should();
chai.use(chaiAsPromised);
});
describe('Application launch', function () {
this.timeout(10000)
beforeEach(function () {
const opts = {
path: './your.exe'
};
const app = new Application(opts);
return app.start().then((app) => {
chaiAsPromised.transferPromiseness = app.transferPromiseness;
return app;
})
})
afterEach(function () {
if (this.app && this.app.isRunning()) {
return this.app.stop()
}
})
it('shows an initial window', function () {
return this.app.client.getWindowCount().then(function (count) {
assert.equal(count, 1)
// Please note that getWindowCount() will return 2 if `dev tools` are opened.
// assert.equal(count, 2)
})
})
})
Run the test by:
mocha spec.js
When I use webpack in nodejs, it can catch every compile error, the watching callback will be called every build end.
const webpack = require("webpack");
const compiler = webpack({
// Configuration Object
});
const watching = compiler.watch({
/* watchOptions */
}, (err, stats) => {
// Print watch/build result here...
console.log(stats);
});
But when I use webpack-dev-server, the listen callback only called once when the server started, its there any way to catch every compile error when use webpack-dev-server in nodejs?
const compiler = Webpack(webpackConfig);
const server = new WebpackDevServer(compiler, {
stats: {
colors: true
}
});
server.listen(8080, '127.0.0.1', () => {
// only called once
console.log('bla');
});
finally solved this problem with plugin
compiler.plugin('done',callback)
this callback will be called every build done.