03/04/21 - Arnaud Duforat
Everyone knows Electron to build some "native" cross-platform applications. In fact, it runs an embedded Chromium. We can see the architecture like this:
We obtain a web page interpreted by an embedded browser:
But, you expect it, it is fat.
So what are the alternatives?
Some examples:
An example: Haxeui. It can target Heaps that can run on Hashlink VM or compile and run on all operating systems.
React native can target Windows & MacOS with React Native for Windows. React native transpiles javascript components to native components depending on the operating system. With the library vue-native you can also develop with Vue.js. A webview component is available if needed.
Nodegui that uses Qt under the hood to enable the developer to use React or Vue.js to develop native applications.
Electron, Neutralinojs and NW.js can be used to develop web applications embedded in webviews. Electron and NW.js are based on an embedded Node and Chromium, Neutralinojs is based on a C++ web server and a Webkit web client.
Source: official Neutralinojs documentation
Neutralino offers a lightweight alternative for Electron and NW.js:
Same sample app memory consumption | Linux | Windows |
---|---|---|
Electron | ~ 62 - 65 MB | ~ 45 - 50 MB |
Neutralinojs | ~ 8 - 9 MB | ~ 6 - 7 MB |
NW.js | ~ 40 - 42 MB | ~ 40 - 45 MB |
npm install -g @neutralinojs/neu neu create RichTextWindows cd RichTextWindows neu run
Neutralinojs initially loads the contents of app/index.html file (this is specified in neutralino.config.json and app directory has been replaced by resources directory in 1.9.0 version). Create an app directory and add an index.html:
And an app.js:
And run (with the live-reload):
neu listen
It doesn't work... It seems that we can't reach the server port. This issue shows that we have to run the application as an administrator... For security reasons, this does not suit me.
We could bundle the webview into the application to remove the network call if the webview engine is in the same programming language as the application bundle:
We could do it in JavaFX. Let's start from one of my sample projects: JavaFXDesign. After a renaming and removing some useless source code in our case (items, table in home...), we add javafx-web dependency to access to the WebView component. Then we create a WebViewController and a WebView.fxml. Note that since 2015 JavaFX controllers doesn't need to implements Initializable (see: Initializable doc). To see more details, the project is here: JavaFXWebView. To embed a local web page from the classpath see this commit. To embed a Vue.js SPA see that.
Now how to expose a Java object to Javascript in the WebView?
We add a change listener to the WebEngine that inject the Java object to the window object of the Javascript engine.
The translation in code:
A POJO CallFromJs:
And the addition of the listener on the WebEngine:
The result:
And we see that in the Eclipse console when we click on the button:
13:52:37.666 [JavaFX Application Thread] DEBUG webview.CallFromJs - CallFromJs::doIt() called
We demonstrate here that we can get rid of an embedded web server and quickly develop a light desktop application that embed a webview. This opens up the opportunity for us to use javascript libraries for parts of the application. For the impatients, you can find the repository here: JavaFXWebView.