es4x

Logo

EcmaScript Language Support for Eclipse Vert.x

View the Project on GitHub reactiverse/es4x

Reactiverse ES4X

This is the EcmaScript (5.1+) language support for Eclipse Vert.x

Travis branch Maven Central Codecov branch

EcmaScript (or JavaScript from now onwards) can be used with Vert.x, however it’s language level is limited to the underlying Nashorn engine. The engine does support ES5.1 plus some ES6 features. For a full list of supported features please have a look at the compat-tables project, depending on your runtime JDK 1.8 or JDK10 you should have more or less language features.

Links

Goals

The goals of this verticle factory are to offer a NPM development approach first, instead of a java project based approach. This should make the entry level for JavaScript developers quite low, if they are coming from a nodejs background.

Usage

Minimum requirements: Since vert.x is a JVM based runtime, it is expected that Java and Apache Maven is available in the development machine. Also it is expected that both nodejs and (npm or yarn) are available too.

Bootstrapping a Project

Bootstrapping a project should be as simple as:

# create a generic project
mkdir my-app
cd my-app
npm init -y
# init the es4x bits
npx es4x-cli init
# add some dependencies
npm install @vertx/unit --save-dev
npm install @vertx/core --save-prod
npm install @vertx/web --save-prod
# will trigger the download
# of the java dependencies
npm install

As this moment there should be a minimal package.json. To simplify working with vert.x add the package es4x-cli to your devDependencies. During install the package.json should get a set of custom scripts added and it should look similar to this:

{
  "scripts": {
    "postinstall": "es4x postinstall",
    "test": "es4x launcher test",
    "start": "es4x launcher run",
    "shell": "es4x shell"
  },
  "license": "ISC",
  "private": true,
  "devDependencies": {
    "es4x-cli": "*"
  }
}

As of this moment you can follow the normal workflow. For example in order to create a vert.x HTTP server using vert.x web you could add the following dependencies:

{
  "dependencies": {
    "@vertx/core": "3.5.3",
    "@vertx/web": "3.5.3"
  }
}

And in your index.js:

/// <reference types="@vertx/core/runtime" />
// @ts-check
import { Router } from '@vertx/web';

const app = Router.router(vertx);

app.route().handler(function (ctx) {
  ctx.response().end('Hello from Vert.x Web!');
});

vertx.createHttpServer()
  .requestHandler(function (result) {
    return app.accept(result);
  } )
  .listen(8080);

Note that the first 2 lines are helpful if you’re using Visual Studio Code and they will give you proper type hinting and error reporting.

Important note on ES compatibility

Depending on the runtime your application will run, the ES level will be different. You can verify what works and what doesn’t at the kangax compat table project.

For reference you can expect that JDK1.8 will be less feature rich as it only contains 7% of the spec implemented, JDK10 implements 28% while GraalVM implements 97%.

Working with NPM

ES4X tries to be compliant with commonjs modules, however please note that ES4X is NOT a nodejs runtime so no node specific modules are available. For more information on modules please read the modules doc.

Running your app

Since the package es4x-cli is added to the project and the scripts section is using it, running your application is as simple as:

npm start

Debugging your app

When working on the standard JDK you can start your application as:

npm start -- -d

This will start a JVM debugger agent on port 9229 that you can attach for a remote debug session from your IDE (currently only tested with IntelliJ IDEA).

The experimental GraalVM support allows debugging over the JVM agent and also supoprt the Chrome devtools protocol to debug the scripts. In order to activate this mode:

npm start -- -i

And follow the instructions.

Packaging

It is common to package JVM applications as runnable JAR files, the es4x-cli creates a pom.xml with the maven-shade-plugin configured for this:

mvn clean package

And a new JAR file should be built in your target directory.

Packaging will re-arrange your application code to be moved to the directory node_modules/your-module-name so it can be used from other JARs. In order for this to work correctly, the current node_modules are also bundled in the jar as well as all files listed under the files property of your package.json.

Shell/ REPL

When working in a more interactive mode you’ll be able to use the standard Nashorn REPL jjs or Graal.js REPL js or if you just want a REPL to be available in your Graal runtime you can switch the main class of your runnable jar to:

io.reactiverse.es4x.Shell

Using this main will allow you to pass any configuration to your vertx instance by using a kebab case format prefixed with a - sign. For example to start a clustered shell:

java -cp your_fatjar.jar io.reactiverse.es4x.Shell -clustered ./index.js

The if no script is passed then the shell will be just a bootstrapped environment. You will be able to load any module by calling later:

require('./my-module.js');