How can I use CommonJS modules with Oracle's new Nashorn JS Engine? - commonjs

I'm looking for a module system for Nashorn. From what I can tell, CommonJS is the way to go concerning modules for JS. I have looked through the list (here and here) and have found little in the way of a CommonJS implementation for Java.
Narwhal is no longer active and it's documentation is no longer hosted on GitHub. Is there an existing CommonJS implementation which supports Java or should I start a new project?

Have a look at jvm-npm here https://github.com/nodyn/jvm-npm. This project is used by nodyn as the CommonJS module system. It is NPM-aware, meaning you can load modules directly from NPM, but it does not provide any of the Node.js API.
Here is a simple example usage:
$ npm install pegjs
npm http GET https://registry.npmjs.org/pegjs
npm http 200 https://registry.npmjs.org/pegjs
pegjs#0.8.0 node_modules/pegjs
$ jrunscript
nashorn> typeof require
undefined
nashorn> load('./jvm-npm.js')
nashorn> typeof require
function
nashorn> var PEG = require('pegjs');
nashorn> typeof PEG
object
It is primarily all Javascript, but the actual loading of files from the filesystem and such is done using Java.

I asked a very similar question on the Nashorn mailing list a little while back, here's Sundar's (Nashorn Engineer) reply:
From: A. Sundararaj​an
To: nashorn-dev#openjdk.java.net
I forgot to add. Nashorn does not contain any builtin module system.
But, if a module system is pure JS + Java, it must be possible to run
on nashorn.
Nashorn supports "load" (loads scripts from URL, File, resources) and
"loadWithNewGlobal" (loads script but into a fresh global scope)
primitives in addition to the good old 'eval'. So, it should be
possible for any module system to be implemented on top of nashorn in
pure JS or perhaps with a bit of Java code.
-Sundar

I've been looking for such an implementation for a while. I've been using a little patched version of Rhino-Require. Although Rhino claimed to be CommonJS compatible, AFAIK, it implemented only modules and not packages (package.json) can't be parsed.
RingoJS should be compatible. But Nashorn will never be see.
Laterly, Oracle announced project Avatar which relies on Avatar.js or here. It's the official project of what was unofficially called Node.jar. But as of now, you have to compile it by yourself. The project is very young.
Another very young project is Nodyn which relies on dyn.js.
So, if understood well, CommonJs should work with avatar-js and nodyn, but those two are still pretty young. I don't understand why avatar-js in not fully distributed along with nashorn though.
A kind of solution would be to add a CommonJS compatibility script like the one for Rhino which adds importClass/importPackage (mozilla_compat.js) which would add CommonJS compatibility into nashorn, kind of Rhino-Require shim thoroughly tested.

I had the same need, and I used jvm-npm for a while, but I needed something that would work even without allowing usage of Java packages inside JavaScript, so I wrote my own version here: https://github.com/coveo/nashorn-commonjs-modules
It's implemented entirely in Java and supports loading modules from elsewhere than the filesystem (Java resources, a custom database, etc.)
It's published on Maven Central if someone wants to use it.

There's also nashorn-require, you can get that off of github too. I've used it, I was able to do
engine.eval(reader("src/main/javascript/nashorn-require.js"),bindings);
engine.eval("var initRequire = load('src/main/javascript/nashorn-require.js');",bindings);
engine.eval("initRequire({mainFile : 'src/main/javascript/foo', debug : true})", bindings);
engine.eval("var babel = require('babel');",bindings);
and then transpile JSX React components to ES5 with
Buffer input = findTemplateSource(fileLocation,context);
bindings.put("input",input.toString());
result = engine.eval("babel.transform(input,{ presets: ['react', 'es2015'] }).code;",bindings);
Then when I pulled react and react-dom into my browser and loaded the resulting js components, things worked fine, so I'm sure Babel was perfectly happy, though I'm not sure about if it will find 3rd-party plugins or not...

Related

How do I use the results of WP in another plug-in?

I am working on writing a Frama-C plug-in and I would like to know if it is possible to get the weakest precondition of something using WP from within my plug-in, and if so, how exactly? In the past I've used Db.Value, for example, to use the results of the EVA plug-in in my own plug-in. Is there something similar to Db.Value for WP?
The WP plugin exposes its API in the WP.mli file, that is generated by collecting the interfaces of the higher-level modules composing Wp. you can find it in src/plugins/wp/Wp.mli.
However, you should be aware that this API should not be considered stable, and non-backward compatible changes may be introduced in newer Frama-C versions.

Rails asset pipeline with ES6 modules and browserify

I'm trying to implement something with the rails asset pipeline that is proving harder than I'd hoped.
In order to structure the app cleanly, I plan to use a module system for the javascript. For this I want to use CommonJS modules, but I'd like to write them using the new ES6 syntax for future compatibility.
I've found the ES6 module transpiler extension for the asset pipeline, which works well, but this only converts it into the CommonJS format. I still need to get this into JS that the browser understands. For that I'm looking at using Browserify but my problem lies in combining these 2.
The module transpiler works in a per file basis, but browserify works by checking all of the files needed. The problem is that browserify can't use the original files as they're no in CommonJS format, they're in ES6, so it needs the transpiled versions, but because that happens in the pipeline, I can't point browserify at a file.
Are there any ways around this?
You might want to try Seth Vincent's approach, where he uses package.json, and npm scripts to run all JavaScript tasks, and only uses bundle.js in the asset pipeline. You could then shell out to npm tasks from your Rakefile. I like his approach because it opens up the modern JS tool chain for JS tasks.
My recommendation is to use the browserify-rails gem. For ES6, you would use a transform such as this one: https://github.com/thlorenz/es6ify
Update some months later: I still recommend the same path but if you can get off of the asset pipeline, I highly recommend going to webpack or browserify directly. The asset pipeline has some benefits but in my experience, trying to make JavaScript a first-class citizen is painful with it and the benefits outweigh the drawbacks (for me).

scriptcs hosting - Advantages over Roslyn

If I want to support scripting in my application, does scriptcs offer any particular advantages over just using the plain vanilla Roslyn script engine?
Unfortunately there's not much documentation on hosting scriptcs yet, but I'll try to give you a short summary.
Hosting scriptcs in your application provides several features that vanilla Roslyn doesn't:
Pluggable Engines
While scriptcs comes with the Roslyn and Mono engines by default, you can easily replace it with another engine, i.e. F#, LOLcode or even Brainfuck.
Pre-processing
scriptcs will process your scripts and extract things like references (#r) and load other scripts (#load). There was also recently introduced custom ILineProcessors which lets you hook into the pipeline for custom processing. An example processor could look like this:
public class GistLineProcessor : DirectiveLineProcessor
{
protected string DirectiveName
{
return "gist";
}
protected override bool ProcessLine(IFileParser parser, FileParserContext context, string line)
{
var gistId = GetDirectiveArgument(line);
var gistContents = DownloadGistContents(gistId);
parser.ParseScript(gistContents, context);
return true;
}
private static string DownloadGistContents(string gistId)
{
// Download gist contents...
}
}
This processor will download a gist and execute it as part of your script, i.e. #gist 12345678.
NuGet integration
scriptcs has integration with NuGet. This means that if you want scripts to be able to use NuGet packages, just install them and they will automatically be loaded from within the packages folder.
Script packs
Script packs is scriptcs' way to remove boilerplate code. They can import namespaces, reference assemblies and expose functionality to scripts through Require<T>(). See Martin Doms' excellent blog post about building a scriptcs script pack. For a comprehensive list of available script packs, see Script packs master list.
REPL
As you probably know, scriptcs has a REPL. This can be reused in your own application to provide an interactive scripting session.
Debugging
Using the vanilla Roslyn script engine, you can't debug scripts very easily. scriptcs gives you the ability to debug scripts with source mapping through #line directives inserted during pre-processing.
I may have forgotten something, but these are the main points for choosing scriptcs over vanilla Roslyn. When it comes to the actual hosting, you have two options:
ScriptCs.Core
This is a super lightweight library that contains the core components of the scriptcs pipeline. However, it doesn't contain implementations for IScriptEngine (the engine that actually executes code) and IInstallationProvider (the component that installs packages, i.e. NuGet), these live in ScriptCs.Hosting and ScriptCs.Engine.Roslyn. If you use this library, you will have to do all the wire-up of the components yourself and you also need to provide an implementation for the engine and the package installer.
ScriptCs.Hosting
ScriptCs.Hosting is a convenience layer for hosting scriptcs in an application. It's used internally in scriptcs.exe and does all the wire-up of the components (via Autofac) for you. It contains the NuGet implementation for the package installer and has a dependency on ScriptCs.Engine.Roslyn by default. This is the preferred way to host scriptcs as it provides a ScriptServicesBuilder to easily replace scriptcs' internal services. See scriptcs' Program.cs for example usage.
This could sound confusing so if you have questions, please ask on JabbR, Github or on the Google Group.

manage and compile large emberjs app

Ember don't seems to play well with requirejs or building with r.js without some hackery.
Bit hard to manage a large application, I like to break down my file structure as HMVC, which manages modules bit easier :
app
- blah
- modules
-module1
- controller
- model
- view.
Has anyone come up a build stack to automate the compilation into single file with dependency management?
Update: You should now be starting new projects using ember-cli, which provides all the build/dev tools plus many other useful features.
Original answer:
An example Ember project using grunt.js as a build system:
https://github.com/trek/ember-todos-with-build-tools-tests-and-other-modern-conveniences
I've used this as a starting point for some Ember apps and it works well.
Ember don't seems to play well with requirejs or building with r.js without some hackery.
Why do you want to use require.js in the first place?
As for making this all work you'll need a build tool. I recommend brunch (Node) or iridium (Ruby). Brunch is more simple and supports many different module formats. Iridium is much more powerful. It uses Minispade for modules. Require.js/AMD is not needed because your js is always delivered as a single concatenated file.
For stand-alone ember dev I use ember-skeleton as a starting point, which is itself based primarily on rake-pipeline.
https://github.com/interline/ember-skeleton
This provides the whole kit-and-kaboodle for beginning an app, but the meat of it is the rake-p Assetfile, which describes how rake-pipeline will digest all the files, filter their contents, and ultimately combine them into the final handful of files. Additionally, the combination of loader.js and the minispade filter allows the use of 'require()' statements for managing dependencies amongst your files.

What's the difference between javax.servlet.jsp:jsp-api:2.1 and org.mortbay.jetty:jsp-api-2.1:6.1.5?

I am cleaning up a build system for a product that uses Jetty. Currently the project has
javax.servlet.jsp:jsp-api:2.1
as a dependency. Given that I am using Jetty for my project I suspect using
org.mortbay.jetty:jsp-api-2.1:6.1.5
would be the better option. Am I right/wrong? Can they be used interchangeably? Does jsp-api-2.1 leverage a different implementation? Or is it simply a repackage if jsp-api to assert compatibility with Jetty?
I've been trying to find information about this on the web, so far nothing has come up.
Update: Seems like org.mortbay.jetty:servlet-api-2.5:6.1.5 and javax.servlet.jsp:servlet-api:2.1 have the same relationship.
Jetty has a long and colorful history with jsp, having no jsp implementation of our own we have leveraged other implementations often, judging by the version numbers your looking at those are very old versions where we were maintaining patches on top of the glassfish jsp implementation. I think it was a patch for supporting logging in jetty and then a bug fix or three.
Now a days we have been using the jsp artifacts from the java.net project which was spun out from glassfish a while back. However that doesn't seem to be tracking bug fixes very regularly either so we are kicking around trying the jasper implementation in tomcat.
Back on your question, the jsp-api artifacts are typically just repackaged artifacts since the api doesn't change frequently. We historically rebundled them to keep them paired with the patched implementation.
Now, you are obviously using a jetty-6 setup since your still using org.mortbay packaging but jetty6 and jetty7 are both servlet-api 2.5 so you might be able to get away with using the jetty7 jsp setup, we have a handy pom that declares these artifacts here:
http://central.maven.org/maven2/org/eclipse/jetty/jetty-jsp/7.6.5.v20120716/jetty-jsp-7.6.5.v20120716.pom
These are glassfish bundles as well, repackaged and made into osgi bundles in the process so they can be used with jetty in osgi environments....they ought to work normally though, we package them in our jetty7 distributions.