How to create a node.js Native Image with GraalVM - javascript

I am trying to create a native image from a simple node.js example.js application.
When running the application with:
node --native -i --native example.js
then the application is starting and working as expected.
Now I would like to create a native image. I tried the following command:
native-image --language:js example.js
however it is not working, because of the error:
Build on Server(pid: 77626, port: 64052)
[example.js:77626] classlist: 3,964.04 ms
error: Main entry point class 'example.js' not found.
Error: Processing image build request failed
As a resolution I created a main entry point in example.js such as:
function main(args) {
console.log("Main app started")
}
however this doesn't work.
Is there a way usually native images are create for js/node.js applications?

No. Currently, as of Dec 2018, creating GraalVM native images for node.js applications is not possible. The native image utility takes Java bytecode and compiles it ahead of time. GraalVM JavaScript engine is a Java program and can be compiled as a native image. This is what you actually run when you execute $GRAALVM_HOME/bin/js. It still loads JavaScript at runtime, interprets it and compiles it just-in-time to machine code.
GraalVM's node implementation is a normal node, a native application, with the JavaScript engine replaced by the GraalVM's one.
The GraalVM team is experimenting with possible ways to save precompiled parts of the JavaScript programs, maybe a standard library, or parts of your application, but when this can become available and in which form is unclear.

AFAICT there are two sides to JS support in GraalVM: "vanilla" JS support and nodejs support.
Oleg's answer here https://stackoverflow.com/a/53749052/202168 explains clearly why building a native image for a nodejs app is not possible.
However it appears that it is possible to build a native image that runs "vanilla" JS:
https://www.graalvm.org/examples/native-image-examples/#polyglot-capabilities
You can also experiment with a more sophisticated ExtListDir example, which takes advantage of GraalVM’s Java and JavaScript polyglot capabilities.
The code for that example is found at:
https://github.com/graalvm/graalvm-demos/blob/master/native-list-dir/ExtListDir.java
In this case there is a Java 'wrapper' for the JS app. I believe this is a necessary part - in other words the GraalVM does not "compile JavaScript to native" but rather it compiles a Java app which includes a Javascript engine implemented in Java.
Maybe this is what Oleg means by "The GraalVM team is experimenting with possible ways to save precompiled parts of the JavaScript programs" i.e. to have some standard Java boilerplate for running JS apps, so you could directly compile a pure JS app to native image. I guess this would effectively be something like Node or Deno but implemented in Java.
The other side of the problem is if you want to use NodeJS features or include code from npm modules in your JS app.
GraalVM states that the Javascript engine implements ES11, basically all of modern JS:
https://www.graalvm.org/reference-manual/js/JavaScriptCompatibility/
It seems like it might be possible to use JS tooling like http://browserify.org/ to convert nodejs JS code into "vanilla" JS that could be run by Graal's JS engine.
Then with appropriate Java wrapper code you could compile all that into a native image.

Related

Compiling Node.js into an executeable without putting the entirety of Node.js in there

So, I'm trying to pack a simple hello world script into an executeable, yet when using pkg or nexe, it looks like the entirety of Node.js get's packed in there, as they are way bigger than they need to be (around 30 MB). I did stumble upon EncloseJS, however, it was last updated in 2017 and no longer works (and the owner themself advices you to switch to pkg).
So, are there any other things out there that can compile it better than that?
Thanks in advance!
Also: This is the stunningly complex script that needs to run
console.log("StackOverflow is amazing!");
setTimeout(() => {
process.exit(0);
}, 2000);
And my locally installed versions:
NPM
Node
6.14.12
14.16.1
No, pkg and nexe works like that - they melting your code and NodeJS in one executable. Because, basically, you need NodeJS to run nodejs scripts - there is some specific methods like fs, for example, witch not exist in regular js.
Anyway, on this moment there is some projects to view:
NectarJS - project with actual dev status, basically compiles JS to C. But their main objectives is pretty interesting.
There is small JS engine called QuickJS witch compiles JS to C.
Another option is ts2c witch translate JS to C, but it does not
support much features.
But keep in mind, that non of them works as good as pkg, witch fully support latest JS features and all NodeJS methods.

JavaScript vs Node.js

I have simple "to-do" application written in JavaScript and HTML. I don't even have CSS file, just have bit of in-line style in index.html file where I have linked my JavaScript file. No database or any other stuff needed. Simple app using vanilla JavaScript and HTML.
I have AWS free tier account and tried zipping .js and .html files and deploying to AWS Elastic Beanstalk but it's converting into node.js and keep looking for JSON file and deployment is unsuccessful.
Is this called JavaScript app or Node.js app in real world?
How do I deploy it in AWS?
As other have answered (without telling you how to do it) the solution is static web file hosting. You do not need to deploy your app to Elastic Beanstalk as your JavaScript are not executed on the server. They just need to be served to a client where they will execute in the client’s browser.
Amazon S3 is the most cost effective way to serve static HTML website.
The easiest way to setup S3 and deploy your application is to use amplify command line.
See the detailed procedure at https://aws-amplify.github.io/docs/cli/hosting
To learn more about Amazon S3 web hosting, please read this https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html
You are a bit confused on the two "terms" -> Javascript and NodeJS.
Javascript: is a high-level interpreted programming language;
NodeJS: is an open-source, cross-platform JavaScript run-time environment that executes JavaScript code outside of a browser.
So, in your case, since you are not using any "backend", as suggested by other users you should use a simple web hosting.
Node.js is a Runtime Environment to run Javascript Code on the server i.e. on any machine with an operating system. So all Node.js apps will be Javascript apps but not all Javascript apps will be Nodejs apps.
In your case since you have an HTML file and your javascript file might be manipulating the DOM it would be classified as a Javascript app for the browser.
However if you have a javascript file which is not manipulating the DOM, you can run that on a Node.js environment.
I hope i have answered your first question, although i cant answer your second question at this moment.
JavaScript is a language.node.js is not a language or a special dialect of JavaScript - it's just a thingamabob that runs normal JavaScript.All browsers have JavaScript engines that run the JavaScript of web pages. Node.js is simply the V8 engine bundled with some libraries to do I/O and networking. so that you can use JavaScript outside of the browser, to create shell scripts, backend services or run on hardware.

Call binary from React Native?

Is it possible to include and exec a compiled binary inside a React Native project? I'm exploring handling the business logic in React Native with languages other than Javascript, but still have the compiled code be cross platform.
You can access native modules, so uncompiled source code in either Java or Objective-c / Swift is possible. Compiled binaries are always compiled for one platform, which means that you can not link such binaries in to react native. For moving the logic away from Javascript, you have two options
Connect a web server and store most of the business logic there, so use the iOS / Android app mostly as a view layer.
Find a transpiler, that transpiles the language you would like to use to Javascript

Hip-Hop PHP for Node.js?

Is there any way to achieve compiling Node.js scripts as native code, like Hip-Hop does for PHP?
I'm not talking about libraries/apis.
Node.js uses Google's V8 javascript engine which does compile all the javascript to native code.
You don't really need to pre-compile on your own. IIRC, in node, V8 compiles your js before it even runs a single line. So, where with PHP you're code is constantly being interpreted (unless you have some opcode caching in place), with node, you're code is compiled once when you start your application, and (if you're running a server) users that connect will invoke that same code that was already compiled when the server started.
No, You cannot compile Node.js into native code. But you can write parts of your application in c++ using v8. But beware, the transition time of changing from js to c++ world is big.
You can also try to get the intermediate compilation from v8. But I haven't seen anybody doing that.

Javascript for command line utilities

Given a need to write command line utilities to do common tasks like uploading files to a remote FTP site, downloading data from a remote MySQL database etc.
Is it practical to use JavaScript for this sort of thing? I know there are JavaScript interpreters that can be run from the command line, but are there libraries for things like FTP and database access the way there are for e.g. Java? If so, what's the best place to look for them? (Google searches with JavaScript in the keywords always seem to return many pages of browser specific things.)
And is there a way to package a JavaScript program up as a standalone executable on Windows?
Update: I've decided Python is a better tool for this kind of job, but the answers to the original question are still good ones.
Standalone executable?
By the way you ask the question, I'm not sure if you are aware, but the Windows Script Host - included in Windows - allows you to run .js files from the command-line. Your javascript will not be an executable, it will remain a script, a text file. The script runs within cscript.exe, which is provided by WSH. There's no compilation required. Maybe you knew all that.
I use Javascript this way for various utilities on Windows.
I think your instinct is right on the availability of libraries. You are sort of on your own to find all those things. Although, once you find them, it's not hard to package Javascript libraries as COM components and allow re-use from anywhere. See here for an example of packaging the Google Diff/Patch/Match Javascript library in COM.
Addendum: Once a bit of code is available within COM, it can be consumed by any Javascript running on the machine. Some examples of COM objects available to Javascript scripts running in WSH:
MSXML2.XMLHTTP object - used in AJAX, but can be used for any HTTP communication. There also an object for the XSLT engine so you can do transforms from script.
Excel.Application - allows you to open up Excel spreadsheets and automate them from Javascript.
Communicator.UIAutomation - automate MS Communicator (send IM's via script)
COM objects for Google Earth.
SlowAES - an all-Javascript implementation of AES encryption.
You can use Rhino to compile Javascript into Java byte code, and get access to all Java libraries.
Or you could use JScript.net, and get access to the .net libraries. .net includes a jsc.exe that produces exe-files.
Both of these requires the respective framework to be installed to be able to run.
Node.js is by far the best environment for running non-browser JS. I've used Rhino and SpiderMonkey, and there's a pretty huge difference in everything from the basics like how errors are handled to the size of the community using the tool. Node is pitched for "server-side" JS - building server apps in JS. It's great for this. But it works equally well for building command line tools.
The NPM package manager (bundled with Node) provides a nice global directory for finding and installing packages. It works much better than other language equivalents like PECL / Pear / CPAN / etc. Several high quality tools like JSHint, The Jade templating language, and the CoffeeScript compiler are all already available through NPM/Node:
npm install -g jshint, coffee-script, jade
jshint my_code.js
jade < my.jade > my.html
For args parsing, there are packages like commander.js. I currently use a heavily extended version of Commander in my underscore-cli command-line tool.
For messing with JSON or for doing command-line JS work (similar to "perl -pe"), check out underscore-cli - It's a really powerful tool for processing JSON data, processing underscore templates, and running JS expressions from the command-line. I use it for 1001 different things that would otherwise be really annoying to accomplish.
Rhino is bundled with JDK 1.6, jrunscript.exe in the bin directory will allow you to run any Javascript you want. Since it runs under Java you get access to any Java libraries that you may have.
We use it from the command line extensively. It's very good at that.
One way is to write these utilities as AIR applications - They can be written in JavaScript and need not have a UI. They have access to the command line, and there are existing ActionScript 3 libraries that can handle FTP etc. These ActionScript APIs can be called from JS, in AIR applications. AIR applications also have access to a sqlite database.
jslibs is a good standalone JavaScript runtime that support many 3rd party open source libraries like zlib, SQLite, NSPR, libiconv, libTomCrypt, OpenGL, ...

Categories

Resources