Javascript JSonnet via go-jsonnet and gopherjs

227 views
Skip to first unread message

Tess Daniel

unread,
Mar 6, 2020, 1:50:41 PM3/6/20
to Jsonnet
For the benefit of others who need to run jsonnet through a web browser, here's a series of steps I've used to get a usable browser version:

1) Install Go (https://golang.org/)
2) Get the go-jsonnet source into a directory (either by git clone https://github.com/google/go-jsonnet.git, or by download)
3) Open a command line that has access to go
5) Navigate the command line to the go-jsonnet directory
6) Run: GOOS=linux gopherjs build ./cmd/jsonnet
 - This should generate 'jsonnet.js' and 'jsonnet.js.map'. The GOOS tag may be unneeded on some systems.
7) Modify the end of `jsonnet.js` - the last few lines should look like this:

$go($mainPkg.$init, []);
$flushConsole();

}).call(this);
//# sourceMappingURL=jsonnet.js.map


Replace that with the following:

var $global = this;
$global.jsonnetPackage = $packages["github.com/google/go-jsonnet"];
$global.jsonnetPackage.$init();
$global.jsonnet = $global.jsonnetPackage.MakeVM();
}).call(this);
//# sourceMappingURL=jsonnet.js.map

This will give direct access to the jsonnet package, and a prepared VM that can be used globally. Try `jsonnet.EvaluateSnippet(filename, snippet)`, or for different operations, use `jsonnetPackage.SnippetToAST(filename, snippet)`. Alternately, export the entirety of $packages for deeper (but more manual) access.


Note: I make no claim that this is the best way to do this. It's quick and it makes readable code, but it's not a good build process.

It's possible Gopher isn't even the right tool - it refuses to export a package as a library, opting instead to run a single entry point on-load. It builds every package in a way that's fully usable in a browser - it just won't expose them.

An solution that uses Gopher would be to write a library interface that manually exports each object and method. This is not easy to write in Gopher, though. A naive approach of assigning the constructors to global variables had negative results; none of the object bindings made it through, and it was overall much less usable than just pulling the $packages list out of the compiled source.

Another solution might be compiling through the now-abandoned jsgo.io; it's designed specifically to make packages into single exports, and it has a local version. I was not able to get it to install, however.

Emre Kabakci

unread,
Mar 11, 2020, 4:48:21 AM3/11/20
to Jsonnet
Hey Tess,

Thanks a lot for the tutorial! I followed the steps in my local environment but couldn't make gopherjs command work. I run `go build` and even `go get github.com/fatih/color` but somehow gopherjs is looking for the sources and these commands don't put the dependencies into the `/Users/buremba/go/src` directory, it's all in `/Users/buremba/go/pkg` directory. Here is the error:

cannot find package "github.com/fatih/color" in any of:
/usr/local/Cellar/g...@1.12/1.12.17/libexec/src/github.com/fatih/color (from $GOROOT)
/Users/buremba/go/src/github.com/fatih/color (from $GOPATH)

I also tried it on an Ubuntu server but the error is the same. I don't want to take your time as a Go newbie, is it possible for you to share these 'jsonnet.js' and 'jsonnet.js.map' files generated by gopherjs? 

Thanks in advance!
Message has been deleted

Tess Daniel

unread,
Mar 11, 2020, 10:59:31 AM3/11/20
to Jsonnet
Emre,

I'm afraid I can't do so. I'm not affiliated with the project and am not able to send code to this mailing list - nor should I have that privilege.

Emre Kabakci

unread,
Mar 18, 2020, 6:00:27 PM3/18/20
to Jsonnet
Hey Tess, 

No worries, I got help from one of my friends who is familiar with Go. The main reason that I wanted to use the GopherJS output was the SnippetToAST method but it looks like the AST generated loses the type information which is required to walk the tree. Therefore, it's not possible to walk the tree of the AST. The compiler seems to be working just fine though. It's 40% faster compared to Emscripten version and the error outputs are easy to parse.

Dave Cunningham

unread,
Mar 19, 2020, 6:54:51 AM3/19/20
to Emre Kabakci, Jsonnet
That's awesome.

What information specifically did you say is lost?  And why did you need it to walk the tree?

--
You received this message because you are subscribed to the Google Groups "Jsonnet" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jsonnet/0faa7ce0-aa93-4581-aad0-2c33c4170c9e%40googlegroups.com.

Emre Kabakci

unread,
Apr 1, 2020, 10:11:10 PM4/1/20
to Jsonnet
Hey Dave,

Sorry for the delay. The Go structs are converted to JS objects by GopherJS as expected but I couldn't find a way to extract the struct name from those generated JS objects when I tried it as Gopherjs doesn't actually use JS classes under the hood. I couldn't find any information in Gopherjs as well but when I inspected the objects in the console, I found out that I'm able to get the struct name using the proto (i.e.: astNode.__proto__.constructor.string). It's not convenient but works anyway.

I'm working on a browser-based editor based on Monaco (the editor that is used by VSCode). It already has support for JSON Schema and I created a proof-of-concept for the Jsonnet integration by using the Jsonnet compiler to create the JSON data and leverage Monaco's JSON Schema support in order to validate the files using our JSON schema definitions. I do the following steps in order to implement validation in Jsonnet:

1. Once I have the JSON output from the Jsonnet compiler, I validate the JSON output using my JSON Schema and generate JSONPath for each error.
2. I find the AST node that represents the root output.
-- if the jsonnet source is as follows:

local a = 4;

{
  b
: a
}


-- I simply ignore the ast.Local nodes and find the ast node ast.DesugaredObject as follows:
{
  b
: a
}
3. Find the AST node that represents the JSONPath using the ast.DesugaredObject generated by step 2. If the JSON is generated dynamically, I'm not able to find the relevant node but that's fine, I just to the best-effort and the editor highlights the relevant part. 

We actually talked about it a few months ago in this discussion: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!topic/jsonnet/4qNlvw1VGXE

Do you have any plans to make use of Gopherjs in order to replace the Emscripten version of the Jsonnet compiler?
To unsubscribe from this group and stop receiving emails from it, send an email to jso...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages