You will probably have to use the Node.js child_process module. It can spawn a new process and execute a script (e.g. a python file). You'll have to communicate via the standard output streams (stdin, stdout, stderr). It's not super trivial.
Depending on what you need from numpy, I would simply look for a package that contains that functionality. And instead of trying to run MetaTrader5 python package, I'd probably just directly hook up to their websocket API.
You don't need to use an Electron specific UI toolkit, any web UI toolkit should work fine. The only thing that makes Photon particularly suitable for Electron apps is that the components are designed to look like a desktop UI, and is mostly styled like OS X.
Personally I'm using Semantic UI (http://semantic-ui.com/) at the moment, which I find very easy to use. You could also use Bootstrap, Foundation, or any other web UI toolkit. You won't get the native look and feel of Photon, but you'll have more flexibility in design compared to Photon. You can probably find themes for major UI libraries that emulate desktop OS styles too.
I really like the thumbnail preview.
I'm the author of a similar app:
I took more of a 'table' approach for managing the documents but I still love the thumbnail design you selected.
I think I'm going to end up implementing both at some point. I think each has its pros and cons.
Polar is Open Source too if you wanted to collaborate.
You won't be able to share scope that way across windows, this is intentional. You could use postMessage to send some serialized data to the new window, but you'll have to have separate JavaScript for that load in the new window.
https://electronjs.org/docs/latest/api/browser-window-proxy
There are other more common ways to handle cross window communication with multiple BrowserWindow instances and the ipcRender module. If I was sure whether you tried those I'd suggest doing that first since you'll be able to find examples online of how to pass data between windows.
I would like to start with saying that you should not load remote content (e.g. scripts and HTML templates from web servers) without taking measures to sandbox that content in Electron since that puts your users computers at high risk.
See: https://electronjs.org/docs/tutorial/security#checklist-security-recommendations
With that said, that might also be the thing that is causing your problems if Electron has restrictions when it comes to remote content.
What does the network tab say when you open up Developer Tools?
Edit: This is the block that prevents your scripts from running and contains a description on why it's bad to remove the block: https://electronjs.org/docs/tutorial/security#8-do-not-set-allowrunninginsecurecontent-to-true
I would not recommend to use any UI Builder. My feeling is, that you would regret it at some point. In my opinion you should spend a couple of days learning a popular UI Framework like Bootstrap (https://getbootstrap.com/). Youtube and the internet is full of documentation.
I believe you have to serve a static file in the built app rather than using the react web server running in development mode. This guide covers the changes needed to the “win.loadURL” code for development vs production. https://www.freecodecamp.org/news/building-an-electron-application-with-create-react-app-97945861647c/
You could use something like https://obfuscator.io to make your code unreadable.
This should make it harder for the user to edit the code an allow themselves access.
For license management you could also use https://gumroad.com. They have a landing page, payment modules, license verification, and even coupon code system.
Good luck on the project 🤟
In your electron.js file, it looks like url.format is referencing a variable 'url' that isn't referenced correctly. Given that I'm assuming you're looking to use the nodejs url module, and 'url' is a nodejs utility module, you could throw something like...
const url = require('url');
in the top of your document and it should do the trick if I'm understanding this right.
As stated, I'd recommend using something like spawn for this, and then, depending on what kind of analysis you want to make, you can actually analyze on the fly via a readStream
But with Electron we have a dedicated api for this called ipcRenderer. See here... https://electronjs.org/docs/api/ipc-renderer
Ideally for this to be secure, you want to whitelist a number of channels and define who can call them and what precisely happens when messages are sent over each of these channels. You then want to make sure that your render processes dont listen or communicate with eachother directly but through the main process.
edit: added more info
> the user never navigate away from it
This may be possible, but won't be simple -- even if you set it up where Cmd + Tab and Alt + Tab are not supposed to be able to switch between programs on Mac/Win/Linux it's likely going to fail.
> it has to launch a different local application
Easily possible. Try child_process or it's relatives.
> be able to embed and display other websites
Also easily possible. As qudat pointed out you can use an iframe to directly include another site, but it's not actually required. Another option would be to use jQuery to load an external page, insert it into a hidden part of the current page, parse the data from it and populate your own page with it, and then destroy the inserted hidden part of the page. There may also be other options, but this has been my go-to for years now before Electron even came along, and I still use it there occasionally.
Yea, it's totally doable. I currently do this for my project mStream. It's a music streaming server written in NodeJS and uses electron to add a layer of GUI management tools. The server can run completely on it's own without electron too.
The best way to do this is to write your electron frontned and Node App seperatly. Use the fork command to launch your Node App inside the electron app. You can read more about the fork process here:
https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options
Does it have React DevTools enable by default?
I installed it, but I think I had an error when it tried to install react dev tools.
When I start default project it says "Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools"
Electron runs your app in the main process and the web browser window runs in a child renderer instance. It’s a little involved, but the documentation is decent.
Is your target set to 'electron-renderer' so webpack understands that node APIs are available and don't need to be polyfilled?
https://webpack.js.org/configuration/target/
It does seem weird if you're not actually using those modules in your code though.
Or I think even better, let the main process handle that sort of stuff.
You can call the functions from your renderer via ipcRenderer.invoke() and return the response with a promise.
Here is a freecodecamp link for setting up a react / electron project (in case you're interested).
I followed this setup from freecodeacademy. I'll have to take a closer look to see if there might be some advantages with this template, though it doesn't include TS.
I've written a method to load python scripts in Electron and then pass the data up to React, this used the node child process library "How to spawn a child process - the basics | Node.js" https://nodejs.org/en/knowledge/child-processes/how-to-spawn-a-child-process/ might be useful to you?
Website scalability has a different set of problems than an application on a user's computer. A relatively slow python webserver isn't as much of a problem if you can horizontally scale, it just costs more money.
If your calculations were heavy I would recommend writing that part in Rust or C++:
https://github.com/napi-rs/napi-rs https://nodejs.org/api/n-api.html
Then load that module in the UI process and make asynchronous calls to it, they'll be executed in a different thread pool to the javascript and you'll get all the benefits with a vastly simpler design.
It's sounding like it's just serialisation / deserialisation though.
What kind of hardware is this? Why do you need the third party server? Is that server local? How much control do you have over the hardware?
> I am relying on asnchronous calls and still need to have a 100% unblocked UI.
If all you're doing is serialising / deserialising some data, it's not going to be a big deal to have that on the UI process, you'll have 'some form of that' anyway if you're communicating via IPC.
> This is only possible with additional processes as far as i know, otherwise the main process is blocked and therefore any renderer processes as well.
Blocking on the main process will cause GPU paints to be delayed in renderer processes, hence the recommendation not to do any work on the main process.
It sounds like you're just making some IPC calls against this third party server - you're not going to block in between them and they'll take a trivial amount of time. It sounds like you can just make your app with a single process and you'll probably be fine.
Keeping the code and app modular is an exercise in code quality that doesn't really have much bearing on this architectural decision. You can just have the UI interact with some abstraction layer that actually does the communication.
If your intent is to insist that the PDF be downloaded to a file then the "intent"-style openExternal is going to put you at the mercy of whatever the end-user has configured as the default action to take for PDF files.
I think there are two work-arounds:
If you can control the server from which these PDF files are served, sending the file with the content-type application/octet-stream
rather than application/pdf
may force the operating system to save the file rather than opening it with the default PDF viewer. (It is also possible the OS will just look at the file type regardless of the content-type in which case this won't help.)
If nothing else you can absolutely "manually" download the file and save it to disk - even if you need to submit a referrer
header (or anything else). Use the electron showSaveDialog
to have the user choose the destination you will save to, then use request or the standard http or some other module to download the file (as a stream) then save that file to the location the user selected.
For crypto, if you’re set in writing a server in c eventually, you could just do that now as a native module: https://nodejs.org/docs/latest-v14.x/api/addons.html. Otherwise, as long as you’re using standards (which you always should re crypto), the library shouldn’t matter all the much. Node has crypto
built in. That might provide everything you need.
Yes. By the way, this is called a wrapper. In your case it happens to be a GUI. https://techterms.com/amp/definition/wrapper
You would build your GUI and then it could use node's child-process module https://nodejs.org/api/child_process.html to call your CLI.
Sorry for the bed formatting. Am on phone.
I've done similar with both a USB stick and dual-booting and got it working fine.
You will have to ensure that each computer has the appropriate git user name and email for the repository. You can set this in the project directory's ".git/config" file or just ensure they are the same across platforms. Note, if you know how to set and use environment variables, you should be able to set the pertinent ones listed in "Committing" on this page.
The folder will have persistence but any modules that are platform specific, such as compiled C-based modules, will have to be reacquired and rebuilt each system change. When I did so, I had to reinstall electron with each platform change. Obviously any globally installed packages as with the "-g" option will have to be installed on each platform.
Yes, commits are stored within the project's .git directory.
I've gotta tell ya' up front. Real Python programmers hate this. I mean, you can't believe the level of outrage expressed over on /r/Python about comingling anything with Python.
Python has its own GUI libraries available. They're shitty. Only Python programmers know about and can use these GUI libraries they're not intuitive, they're a pain in the ass to make asynchronous, they look like something from Windows 3.1, etc...
However... Python is brilliant when it comes to almost everything else. For example, one thing I like to do is use Flask to set up HTTP/RESTful endpoints and essentially set them up as remote functions. Use Electron as a front end, and you're done.
Another good way for I/O is websockets. I set up a websocket server in node/Electron and websocket clients on IoT hardware. Whenever data comes in, it's sent to Electron and displayed in real time.
i believe this is what most programs would do, regardless.
https://nodejs.org/en/knowledge/child-processes/how-to-spawn-a-child-process/
if you are doing some wacky server scale thing, then you'd do a message queue with workers.
You can use NodeJs Child Process to do that. I personally have used spawn to extract 7z in the background and another spawn to run a couple of other things simultaneously in my electron app. Based on your design and implementation you might have to enable nodeIntegration in the BrowserWindow.
Electron is two-part. The one part is a Chromium browser containing a V8 Javascript-Engine, and the Blink CSS engine. This is the renderer process. The backend of an electron app is basically just a NodeJS server. So NodeJS-APIs will work there.
Hope that helps!
I would say that this is indeed your best shot, because Electron itself is only a wrapper around a node server, and they'll be definitely the right people to speak to, because as far as I understand your problem, you won't get around writing a native node module to call, which will then be able to pull in the necessary .dll-files.
Have a look here: https://nodejs.org/api/addons.html This may be a good starting point for what you're trying to achieve!
Even if you save the log file in JSON, it is still 40 MB and loading the whole file at once is gonna take a good amount of memory and reduce performance. Just don't load the whole file rather read it through a StreamReader like any of these following ways:
I've done a lot of complex 2D geometry using Three.JS funnily enough, WebGL is a very powerful technology.
I'd recommend looking into react-three-fiber, it's a wonderful API.
https://github.com/pmndrs/react-three-fiber
WebGL is what powers things like Google Maps on the web and Mapbox, maybe look into one of those with a custom tileset?
KaiOS also exists, but this is a OS based on an older version of firefox and intended for Smart feature phones that need low memory requirements. There is an update with Mozilla's support on the roadmap.
clicked on the topic thinking "this is EXACTLY what I'm after", before realizing it was mine. Anyways I can answer some of it. I'm using NSIS 3 to create the installer and am using the LZMA compression to bring it from 160 down to about 50 MB - http://nsis.sourceforge.net/Reference/SetCompressor
There's no way to do this in electron as far as I know. Maybe if you build something in C or use Port Audio, but that's all pretty low level.
​
I've had some success with this: https://rogueamoeba.com/loopback/
Are you using electron builder? If so, you just need to follow their guide and set the cert as an environment variable. If you want to see an example on Travis check out https://qvault.io (go to the GitHub link)
Would be interested too! I started looking into this for my app (https://mockoon.com) but I am definitely not a MacOS user nor developer, and I just don't understand most of what is related to this ecosystem :D
An example with my application Mockoon (https://mockoon.com) which not very big but still has many features: - binaries size between 50 and 60MB - 5 processes when running - around 100 MB RAM taken
> Thinking about moving to typescript with LSP plugin or dart + webstorm. Writing something bigger than a pagesize in js is a nightmare.
Have you considered learning/using Elm?
Sciter uses its own HTML/CSS implementation that I did by myself.
As of dev tools...
Sciter.dll does not include devtools as does ElectronJS/Chrome - absolutely no need for that on end user side (why do we all need to pay by bandwidth for devtools in VS Code for example? No one uses it there).
Instead sciter.dll and scapp.exe (standalone exe form of sciter) contain very small debugging peer that allows to communicate with inspector.exe.
Inspector allows to inspect DOM, files, see console output, and script debugger, see: https://sciter.com/sciter-js-inspector-debugger-preactjs/
> established choice
Just in case, Sciter (circa 2006) was established long before ElectronJS (circa 2013).
Norton Antivirus for example is using Sciter for its UI since 2007. Norton AV alone has 150 mln or so installations. And they are not changing architecture of their applications since then. All 15 years it is HTML/CSS UI adjusting to follow modern trends.
Currently the industry standard is to implement the OAuth 2 Implicit Grant flow in your API and app: https://auth0.com/docs/api-auth/which-oauth-flow-to-use#is-the-application-a-native-app-or-a-spa- and https://www.oauth.com/oauth2-servers/oauth2-clients/mobile-and-native-apps/
It means that the first time the app is started, the user has to log in with credentials. Afterwards a token is stored on that device and is used for authenticating API calls.
What about if you used a webpacks resolve alias feature: https://webpack.js.org/configuration/resolve/#resolvealias
You could then have an environment variable set in your npm scripts that your webpack config reads and changes the import alias for the different contexts.
You cannot run Electron on Android but you can use your application code with the Cordova wrapper https://cordova.apache.org/. In most of the cases the application should remain the same, just packaging changes.
Maybe I'm not looking at the right info, but it doesn't look like Firebase offers any free service that would help here.
They have a "Cloud Functions" service which may be appropriate, but the "outbound networking" is limited to google services only.
You need to prefix the partition name with "persist:". From the docs:
> If partition starts with persist:, the page will use a persistent session available to all pages in the app with the same partition. if there is no persist: prefix, the page will use an in-memory session. If the partition is empty then default session of the app will be returned.
You haven’t set the BrowserWindow as the first argument in showOpenDialog.
It needs to be: ```js import { dialog } from ‘electron’;
Const win = new BrowserWindow(); win.loadURL(‘index.html’);
dialog.showOpenDialog(win, { defaultPath: ‘/Desktop’ }); ```
Edit:
There are a few things I can see are problems.
It looks like you are missing the "main" attribute in the package.json which points to the electron main process javascript. Take a look at https://electronjs.org/docs/tutorial/first-app it should help clear up that issue.
Is there a reason why you have
> pathname: path.join(__dirname, 'resources/app/angular-flask/index.html'),
instead of
> pathname: path.join(__dirname, 'index.html')
I didn't look at Electron until BrowserView was already the standard in their docs. From the docs, it doesn't seem like there's an element to be used in that way, and is only used programmatically
Yeah man, just check this out: https://electronjs.org/docs/api/app#appgetpathname
You can specify (as a string) which special folder you want to grab. That what you're looking for?
It may not be what you're looking for, but if you're utilizing Session for requests, you specify offline emulation: https://electronjs.org/docs/api/session#sesenablenetworkemulationoptions
It's been a while since I've worked with Electron so take this with a grain of salt but I think that your hunch is on the right track. Your react code won't have access to the nodejs process (which is where spawn
comes from) after it's compiled. You'll be able to use node-powershell
inside your main process but not in your renderer process. What you'll want to look at is sending messages with ipcMain
and ipcRenderer
.
Here's a link to the docs for sending messages between the two processes. https://electronjs.org/docs/api/ipc-main
I’ve never used the loadFile method before, but try specifying ./index.html
. If that doesn’t work, the following code should do the trick:
win.loadURL('file://' + __dirname + 'index.html')
No, the javascript running on the page has nothing to do with main.js.
An electron app has two seperate parts. Main and Renderer.
Main, which is what main.js is, will handle the node.js part. The renderer is the actual html, and the javascript attached to it.
https://electronjs.org/docs/tutorial/application-architecture
You can use electron's dialog
api and pass in fs.writeFile
as a callback to save the information wherever the user wants the file to be saved.
If you want to place your own image for the app icon, use this API... https://electronjs.org/docs/api/native-image.
I believe electron builder has it's own API for icons, so if you go that route, it is worth checking it out. I was looking in my own electron projects, and I think it is rendered from a specific folder resources
, but it depends if you're using a boilerplate with it all previously structured that way.
Sure! There’s already an Electron-based app called Shortexts that does something similar, take a look at their app in action: http://shortexts.com/#see_it_in_action
At the very least, you'll want to disable nodeIntegration in the webPreferences. There's no good reason to include it in a BrowserWindow that's loading remote content, and it can cause all sorts of compatibility issues, as well as being a huge security risk.
Also, read this:
My bad, overlooked the fact that you wanted to communicate to inside the webview.
Further reading suggests IPC may still be the way.
https://electronjs.org/docs/api/webview-tag#webviewsendchannel-arg1-arg2-
I've only done some angular tutorials. Each person has their own personal preference. Do whatever keeps you and your code organized.
You can take a look at different apps from the electron app list, and see how people organize their work.
https://electronjs.org/apps
( my app is wonder reader
;) )
For desktop platforms the Electron documentation says:
macOS: 10.9+. Supports 64-bit only.
Windows: 7+. Supports x86 or x64, but not ARM.
Linux: Ubuntu 12.04; other versions may not work but some do (if they have the needed libs). Supports x86, x64, and ARM v7.
For Android, IDK either =\ Nearly impossible to find anything that's not "Are Android/iOS going to be supported" or similar, and most of that is on closed Issues on the Electron's GitHub page.
It does not generate code. It is a JS and CSS library, that you can include. You really have to read the documentation to undestand it: https://getbootstrap.com/docs/4.5/getting-started/introduction/
It's not simple by any means, and IDK how well it would work in production, but you could try to use app.getPath( "exe" ) to get the path where your executable is running and use path.join( executable, "..", "..", ".." ) (with as many ".." as you need, which is probably less).
I've tried this in development and it was working fine to help find a specific part's node_modules folder, but I don't think I ever tried it in a production version of a program; obviously though it's going to require a lot of testing on both sides to get it right (if it even works).
I tried installing
nodejs-legacy and got this http://imgur.com/Q8giwGB
Is there any other way? PD: I have Node & npm installed from here https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
As far as Electron goes, node.js and its npm libraries is the big one. After that, I'm the wrong guy. I would say just choose a popular well documented framework that you like (Angular maybe?).
My focus is more on Python backend and IoT needing a basic front end that others can build on. So, Electron is perfect for me and I just use node and plain JS.
You can send messages both ways between processes.
webContents.send()
in main process and ipcRenderer.on()
in the renderer process. ipcRenderer.send()
in renderer process and ipcMain.on()
in the mainProcessSee docs here.
However if you want to communicate between processes that you have spawned using node's child_process module, then you should use node's inter process communication routines. For example, when you fork a process using require('child_process').fork
, you get a child process instance, you can call send()
and on()
methods on them. Inside the forked process you can listen and reply to these messages using process.on()
and process.send()
. See docs here.