Compile JavaScript? Really?

Written by vladimirmetnew | Published 2017/05/06
Tech Story Tags: javascript | nodejs | conspiracy-theories | web-development | programming

TLDRvia the TL;DR App

WebAssembly, Emscripten and tools for Javascript compilation.

I have two news for you: good and bad.

Good news— epoch of JavaScript compilation has already started.Bad news —we aren’t ready for this epoch yet.

Really?

Maybe you’ve seen this conference talk (“The Birth & Death of JavaScript” by Gary Bernhardt).

Shortly, the main idea of this talk is that — browsers will become a new OSs, JS will become a new C language, the software will migrate into the browser.

Yes, this epoch has already started after Chrome OS, Electron, Emscripten and WebAssembly. Why since Electron? Because Electron app is equivalent to the browser that works as a desktop app. It’s a good first step before web will migrate to web: Before all desktop apps can work in the browser, we can try to run a single desktop app on top of the browser.

What’s the problem with Electron?

The main issue with Electron is simple: Electron is Flash for the desktop(great article about Electron).

For example, I have Slack, Atom, and 3 other apps built with Electron installed on my Mac. It equals to 5 Chromium browsers.

WebAssembly, Emscripten, and LLVM

WebAssembly/design_design - WebAssembly Design Documents_github.com

I’m sure you’ve heard about WebAssembly.

But if you want to use WebAssembly you need to know C or C++. How many frontend developers are familiar with C/C++? Personally, I don’t know such developers in real life.

Right now we can compile C/C++ code to Wasm in 2 ways:

Emscripten

kripken/emscripten_emscripten - Emscripten: An LLVM-to-JavaScript Compiler_github.com

Emscripten makes native code immediately available on the Web.

One of the Emscripten’s purposes was to port existed huge C/C++ codebase to the Web. But currently, JavaScript is one of the most popular languages. It runs inside our browsers, it runs on mobile platforms, it runs on the server(Node). JS codebase is huge too.

JS -> WebAssembly

Personally, I was searching for any tool that can translate JS to language that can be translated to C/C++ or asm.js.And… I didn’t find any such tools.

But you can find a tool to translate <your-favorite-language/>to JS. Almost always this tool exists. It proofs that JS codebase maybe the biggest codebase ever. JS code can be generated with Java, Python, and other languages.

Interesting idea: The Reason language is based on the OCaml’s backend and was developed to generate JS. OCaml bytecode can be translated into C code. It means that Reason (maybe) allows you to write both WebAssembly and JS.

Another approach is to compile JS into LLVM bytecode. Theoretically, that can provide JS compilation into native code and WebAssembly. It’s a crazy idea, but it will be great.

Small note:

JS can be generated from almost every language, but you can generate WebAssembly(that will interact with JS in the browser) only with languages that can be compiled into LLVM bytecode.

But instead of writing C code it will be better to somehow translate JS into WebAssembly.

Tools that “compile” your JS:

Enclose

Compile your Node.js project into an executable

igorklopov/enclose_enclose - Compile your Node.js project into an executable_github.com

It was the first attempt to “compile” JS.There were two versions of Enclose: free and proprietary. Free version could bundle only five files.Also, it looks like Enclose is deprecated. Now the project owner works on Pkg.

Pkg

Package your Node.js project into an executable

zeit/pkg_pkg - Package your Node.js project into an executable_github.com

Recent attempt to “compile” JS.How does it work? Pkg just puts 30MB Node binaries into the executable. So even code like const a = 5 generates a big file.

From node-compiler docs(comparison table):

Pkg hacked fs.* API's dynamically in order to access in-package files.Pkg uses JSON to store in-package files.

Use cases:

  • Make a demo version of your app.
  • Make a cross-compiled executable.

Personally, I’m sure that more suitable name for Pkg is Enclose 2 :)

Main developer of Pkg is Igor Klopov: repo’s pulse here.

And you can check commit history.

Pkg uses devdependency eslint-config-klopov.

Nexe

🎉 create a single executable out of your node.js apps

nexe/nexe_nexe - 🎉 create a single executable out of your node.js apps_github.com

Yet another attempt to compile JS.

There is no official info how it exactly works, but after a small research, I figured out that Nexe downloads Node binaries(like Pkg and Enclose).

Problems:

Node-Compiler

Compiling your Node.js application into a single executable with dynamic require and all fs.* API support.

pmq20/node-compiler_node-compiler - Compiling your Node.js application into a single executable with dynamic require and all fs.* API…_github.com

Node-compiler recommends itself as a better replacement for Pkg and Nexe. As you can see this tool bundles your app with node binaries (I’m not sure, there is no info about how it works).

Also, it’s strange to find a Node.js repo in project repo, isn’t it?

Small summary:

  • Enclose looks like it’s not maintained.
  • <sarcasm> **//**Pkg === (Enclose 2.0: _The Return of the Igor Klopov)_</sarcasm>

  • <sarcasm>Node-Compiler stores Node.js repo in repo. </sarcasm>
  • Nexe is developing, but not so actively.
  • All these projects don’t compile JS, they just pack your code with Node binaries.
  • But they are still great for some purposes because you can pack your code in executable.

Compilation with JS engines

Can we compile JS with V8/Chakra/SpiderMonkey?

Yes, we can. Theoretically. For example, we can take unoptimized compiled (not “JIT-ed”) code from the engine.

No, we can’t. Unoptimized native code is less efficient than JIT-ed optimized code.

Maybe. Every JS engine is a very complicated, confusing system that has own architecture and own features.

If you ask someone about how the browser works, you’ll see that this developer knows only common facts about browsers. And it’s … scary. Because not all programmers know how the system (that executes their code) works.

Conclusion.

  • Electron must be revised.
  • Many frontend developers can’t use WebAssembly because don’t have a C/C++ background.
  • There isn’t any tool to translate JS into another language.
  • JS code can be generated from almost any programming language.
  • Tools that can make executable file exist, but they put Node binaries into your file.
  • Browsers are very complicated and might be better explained to developers.
  • WebAssembly may become a compiled form of JavaScript.

Maybe, JS is the new C language? The Modern C for the modern world.

Github: https://github.com/MetnewTwitter: https://twitter.com/coldlinecallMail: [email protected]


Published by HackerNoon on 2017/05/06