Site icon R-bloggers

Introducing js: tools for working with JavaScript in R

[This article was first published on OpenCPU, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

A new package has appeared on CRAN called js. This package implements bindings to several popular JavaScript libraries for validating, reformating, optimizing and analyzing JavaScript code. It builds on the V8 engine, the fully standalone JavaScript engine in R.

Syntax Validation

Several R packages allow the user to supply JavaScript code to be used as callback function or configuration object within a visualization or web application. By validating in R that the JavaScript code is syntactically correct and of the right type before actually inserting it in the HTML, we can avoid many annoying bugs.

The js_typeof function simply calls the typeof operator on the given code. If the code is syntactically invalid, a SyntaxError will be raised.

callback <- 'function(x, y){
  var z = x*y ;
  return z;
}'
js_typeof(callback)
# [1] "function"

Same for objects:

conf <- '{
  foo : function (){},
  bar : 123
}'
js_typeof(conf)
# [1] "object"

Catch JavaScript typos:

js_typeof('function(x,y){return x + y}}')
# Error in eval(expr, envir, enclos): SyntaxError: Unexpected token }

Script Validation

A JavaScript program typically consists of script with a collection of JavaScript statements. The js_validate_script function can be used to validate an entire script.

jscode <- readLines(system.file("js/uglify.min.js", package="js"), warn = FALSE)
js_validate_script(jscode)
# [1] TRUE

Note that JavaScript does not allow for defining anonymous functions in the global scope:

js_validate_script('function(x, y){return x + y}', error = FALSE)
# [1] FALSE

To validate individual functions or objects, use the js_typeof function.

Uglify: reformatting and optimization

One of the most popular and powerful libraries for working with JavaScript code is uglify-js. This package provides an extensive toolkit for manipulating the syntax tree of a piece of JavaScript code.

The uglify_reformat function parses a string with code and then feeds it to the uglify code generator which converts it back to a JavaScript text, with custom formatting options such as fixing whitespace, semicolons, etc.

code <- "function test(x, y){ x = x || 1; y = y || 1; return x*y;}"
cat(uglify_reformat(code, beautify = TRUE, indent_level = 2))
# function test(x, y) {
#   x = x || 1;
#   y = y || 1;
#   return x * y;
# }

The more impressive part of uglify-js is the compressor which refactors the entire syntax tree, effectively rewriting your code into a more compact but equivalent program. The uglify_optimize function in R is a simple wrapper which parses code and then feeds it to the compressor.

cat(code)
# function test(x, y){ x = x || 1; y = y || 1; return x*y;}
cat(uglify_optimize(code))
# function test(x,y){return x=x||1,y=y||1,x*y}

You can pass compressor options to uglify_optimize to control the various uglify optimization techniques.

JSHint: code analysis

JSHint will automatically detect errors and potential problems in JavaScript code. The jshint function is R will return a data frame where each row is a problem detected by the library (type, line and reason of error):

code <- "var foo = 123"
jshint(code)
#
#       id                raw code      evidence line character  scope             reason
# 1 (error) Missing semicolon. W033 var foo = 123    1        14 (main) Missing semicolon.

JSHint has many configuration options to control which types of code propblems it will report on.

To leave a comment for the author, please follow the link and comment on their blog: OpenCPU.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.