Node-webkit without webkit
Somehow we were discussing desktop applications nw.js. Everything is fine, but the need to distribute the entire browser engine (which over time and the addition of new features does not become smaller and now weighs a compressed 30MB) is depressing.
But what if we make a module for node.js that can display UIs in a system browser?
Under the cut, I’ll tell you about the attempt - how is it, is it worth the effort, can it be used, and what happened as a result.
Basically, the project was made more likely as a proof-of-concept: to play, see, check how it is. I made 3-4 orders on it in the style of “I want a small application with a built-in webview” or “I want a wrapper for the site in the desktop application window”. Maybe someone will find my experience useful, so I posted it in public. Code on github . I won’t describe the nuances of the code in detail, the goal is not to describe the code, but rather to think about the suitability of the result.
The application is statically compiled with node.js with its entry point. When launched, a native module with window display logic is added to the node, and control is transferred to _thirdPartyMain.js (there is such an opportunity in the node). From there, the user main.js is loaded, where the ui module is connected. The module starts the http-server, opens a window with the specified config and directs the webview to the address of the built-in server, which gives user content. The window generates events (moving, minimizing, ...) and can execute methods (for example, close).
ActiveX-th WebBrowser is inserted under Windows (this is the same MSIE, but without tubulars, address lines, etc.). By default, it shows a lot of unnecessary dialogs (which turn off in a strange way), but in general it works as you want. IE, it doesn’t update well , but you had to support XP, so for older versions of Windows you can download a web kit (chrome embedded framework). If necessary, if the user does not mind, the application downloads the libraries, unpacks them and works with the webkit.
Under the poppy, everything is more transparent, WebKit WebView is much easier and more understandable in comparison with IE; under Linux there is webkit-gtk.
It was necessary for applications to be packed into one EXE. The most suitable format was ZIP: it is read from the end, allowing you to append anything to the executable file and unpack it from yourself; SFX also work on this principle. For use from node.js, you can hang a hook on calls to fs and redirect requests to files that are in the archive to a virtual file system instead of reading from disk.
IE and WebKit offer ways to interact both from C ++ to JS, and vice versa. In IE, a javascript object, including a function, is an IDispatch object. If you check the typeof of such an object, the javascript engine will return unknown, these are the so-called host objects (the use of such results of the typeof operator in the ES6 standard is no longer recommended , but nothing was said about non-standard types before). You can call something from C ++ by accessing the window.external object, provided that the host has implemented this method.
In a webkit, similarly, you can add the window property as an object with the methods available for calling.
In the node, the process of creating plugins is well documented . Built-in add-ons are created in the same way, but registered with another macro. After creating the addon class, it inherits from EventEmitter and can generate events by receiving a reference to the emit method.
Node.js intentionally lives in a separate thread so that lengthy operations do not block the UI, so the UV library is used to send messages to the node and synchronize.
It is 2-3 MB (unpacked 7). In principle, you can make the assembly smaller, if you only need to open the page in the application, without node.js (in general, for the sake of size, everything was done).
Because the application does not use additional frameworks, it starts quickly on average 1 second (for the time of the first launch, see below); adding profiling, you can make sure that the main time is spent on initializing the browser.
Windows optimizes the launch of applications and components that you use more often. If IE is rarely used, the first time the application starts is somewhere around 3..10 seconds, depending on the operating system and computer.
Very often IE isused as a tool for downloading the browser and never updated at all (although the situation is improving with the latest versions of Windows). IE cannot be updated forcibly (to show the dialogue, update IE from the application is tantamount to suicide: updating IE is complex, long, often requires a reboot - you can’t mock a user like that, he will just find another application).
The browser versions are tied to the OS: for Windows XP there is no IE10, for OS X Lion there is no Safari 8.
No node.js objects can be used in a browser and vice versa, interaction occurs either as in a classic client-server application (xhr), or in the manner provided by the program (postMessage in a window or node) - i.e. as in web worker, you can transfer only simple data. It was possible to make a context bridge, but firstly it’s difficult and cumbersome, and secondly short-sighted, because ES6 is almost here, and what to do, for example, with a proxy object in IE10 is unknown.
There is an assembly for win / mac / linux, which, in principle, can be used to customize, etc. I use it to create customized "browser applications" when it happens suddenly someone needs it. It is relatively stable, but I didn’t bring it to the mind and release quality, because ...
Applications are rarely downloaded, the Internet is now quite fast (and in case of installing applications, EDGE can really be neglected, because the application is not a site, it will not be installed on the road), there are unresolved problems in using the system browser. In most cases, now the game is not worth the candle and using a web kit seems to be more correct. If the goal is to create a small application mainly for new OSes - or maybe it can be.
But what if we make a module for node.js that can display UIs in a system browser?
Under the cut, I’ll tell you about the attempt - how is it, is it worth the effort, can it be used, and what happened as a result.
Dicslaimer
Basically, the project was made more likely as a proof-of-concept: to play, see, check how it is. I made 3-4 orders on it in the style of “I want a small application with a built-in webview” or “I want a wrapper for the site in the desktop application window”. Maybe someone will find my experience useful, so I posted it in public. Code on github . I won’t describe the nuances of the code in detail, the goal is not to describe the code, but rather to think about the suitability of the result.
How it works
The application is statically compiled with node.js with its entry point. When launched, a native module with window display logic is added to the node, and control is transferred to _thirdPartyMain.js (there is such an opportunity in the node). From there, the user main.js is loaded, where the ui module is connected. The module starts the http-server, opens a window with the specified config and directs the webview to the address of the built-in server, which gives user content. The window generates events (moving, minimizing, ...) and can execute methods (for example, close).
Webview
ActiveX-th WebBrowser is inserted under Windows (this is the same MSIE, but without tubulars, address lines, etc.). By default, it shows a lot of unnecessary dialogs (which turn off in a strange way), but in general it works as you want. IE, it doesn’t update well , but you had to support XP, so for older versions of Windows you can download a web kit (chrome embedded framework). If necessary, if the user does not mind, the application downloads the libraries, unpacks them and works with the webkit.
Under the poppy, everything is more transparent, WebKit WebView is much easier and more understandable in comparison with IE; under Linux there is webkit-gtk.
Application Packaging
It was necessary for applications to be packed into one EXE. The most suitable format was ZIP: it is read from the end, allowing you to append anything to the executable file and unpack it from yourself; SFX also work on this principle. For use from node.js, you can hang a hook on calls to fs and redirect requests to files that are in the archive to a virtual file system instead of reading from disk.
Browser interaction
IE and WebKit offer ways to interact both from C ++ to JS, and vice versa. In IE, a javascript object, including a function, is an IDispatch object. If you check the typeof of such an object, the javascript engine will return unknown, these are the so-called host objects (the use of such results of the typeof operator in the ES6 standard is no longer recommended , but nothing was said about non-standard types before). You can call something from C ++ by accessing the window.external object, provided that the host has implemented this method.
In a webkit, similarly, you can add the window property as an object with the methods available for calling.
Interaction with node.js
In the node, the process of creating plugins is well documented . Built-in add-ons are created in the same way, but registered with another macro. After creating the addon class, it inherits from EventEmitter and can generate events by receiving a reference to the emit method.
Node.js intentionally lives in a separate thread so that lengthy operations do not block the UI, so the UV library is used to send messages to the node and synchronize.
What happened well
Application size
It is 2-3 MB (unpacked 7). In principle, you can make the assembly smaller, if you only need to open the page in the application, without node.js (in general, for the sake of size, everything was done).
Launch time
Because the application does not use additional frameworks, it starts quickly on average 1 second (for the time of the first launch, see below); adding profiling, you can make sure that the main time is spent on initializing the browser.
Problems
First start
Windows optimizes the launch of applications and components that you use more often. If IE is rarely used, the first time the application starts is somewhere around 3..10 seconds, depending on the operating system and computer.
Browser versions
Very often IE is
The browser versions are tied to the OS: for Windows XP there is no IE10, for OS X Lion there is no Safari 8.
Javascript contexts
No node.js objects can be used in a browser and vice versa, interaction occurs either as in a classic client-server application (xhr), or in the manner provided by the program (postMessage in a window or node) - i.e. as in web worker, you can transfer only simple data. It was possible to make a context bridge, but firstly it’s difficult and cumbersome, and secondly short-sighted, because ES6 is almost here, and what to do, for example, with a proxy object in IE10 is unknown.
What is
There is an assembly for win / mac / linux, which, in principle, can be used to customize, etc. I use it to create customized "browser applications" when it happens suddenly someone needs it. It is relatively stable, but I didn’t bring it to the mind and release quality, because ...
conclusions
Applications are rarely downloaded, the Internet is now quite fast (and in case of installing applications, EDGE can really be neglected, because the application is not a site, it will not be installed on the road), there are unresolved problems in using the system browser. In most cases, now the game is not worth the candle and using a web kit seems to be more correct. If the goal is to create a small application mainly for new OSes - or maybe it can be.