Successfully reported this slideshow.

Grooscript gr8conf

630 views

Published on

Grooscript is an open source project, a little framework that convert groovy code to javascript, more info in grooscript.org.

Javascript is cool now, a vibrant community with many new developments. Web development is moving to client size and you must be start to worry about javascript and all the new awesome tools for it. With grooscript, you can join this new wave with our lovely groovy. You can code all the logic of your application in groovy, test with spock, use gradle or any other java or groovy framework. Grooscript will convert your application code to javascript and then you can use it in the browser or Node.js.

In this talk I will introduce about grooscript, how started, how can be used, explore its limitations,… Also I will show grooscript grails plugin, and what do you can do with it. We will take a look at Node.js plugin and gradle plugin, and how to use this tools. I will show some demos of different ways to use grooscript.

Published in: Software, Technology
  • Be the first to comment

  • Be the first to like this

Grooscript gr8conf

  1. 1. grooscript @grooscript http://grooscript.org Jorge Franco 0.5
  2. 2. About me Developer, I love it Lazy in english at school Living in Madrid Working at Osoco Grooscript developer @jfrancoleza jorge.franco.leza@gmail.com
  3. 3. The players
  4. 4. Web developer Leave your comfort zone Move to the client side
  5. 5. Doesn’t run! on browsers
  6. 6. Do something! No excuses You can do a library, resolve issues, create a plugin, give feedback, help other projects, … ! You will learn a lot
  7. 7. The wire
  8. 8. Groovy to Javascript converter Groovy 2 to Javascript ECMAScript 5 Open source project, Apache 2 license Library with Groovy and GPars dependencies No special Javascript objects or functions Converted code requires grooscript.js to run Different conversion options Grails plugin, npm package, gradle plugin What is grooscript?
  9. 9. File.groovy File.js Conversion! Options grooscript.js Convert Groovy files
  10. 10. Groovy code def sayHello = { -> println "Hello ${it}!" } [‘Groovy', ‘JavaScript', 'GrooScript'].each sayHello ! assert [1, 2, 3].size() == 3 class Amazing {} ! amazing = new Amazing() amazing.metaClass.who = [] amazing.metaClass.add = { who << it} ! amazing.add 'Rafa Nadal' assert amazing.who.size() == 1
  11. 11. Javascript result function Amazing() { var gSobject = gs.inherit(gs.baseClass,'Amazing'); gSobject.clazz = { name: 'Amazing', simpleName: 'Amazing'}; gSobject.clazz.superclass = { name: 'java.lang.Object', simpleName: 'Object'}; if (arguments.length == 1) {gs.passMapToObject(arguments[0],gSobject);}; return gSobject; }; var sayHello = function(it) { return gs.println("Hello " + (it) + "!"); }; gs.mc(gs.list(["Groovy" , "JavaScript" , "GrooScript"]),"each",[sayHello]); gs.assert(gs.equals(gs.mc(gs.list([1 , 2 , 3]),"size",[]), 3), null); amazing = Amazing(); gs.sp((amazing = gs.metaClass(amazing)),"who",gs.list([])); gs.sp((amazing = gs.metaClass(amazing)),"add",function(it) { return gs.mc(gs.fs('who', this),'leftShift', gs.list([it])); }); gs.mc(amazing,"add",["Rafa Nadal"]); gs.assert(gs.equals(gs.mc(gs.gp(amazing,"who"),"size",[]), 1), null); Class Default constructor Function New
  12. 12. Javascript Groovy Java MoreJavascriptfriendly Types, inheritance, java 8, … metaClass Lists Closures Operators Dsl’s Expando Maps beans methodMissing Mixins Categories Traits delegate propertyMissing
  13. 13. Using converted code in javascript Create classes NameClass(); Default constructor with js object NameClass({property: value, data: 1}); Call methods, basic parameters myObject.method(params); Access properties myObject.property = 4; Use functions as closures list.each(function () { … }); Traits Metaprogramming Mixins, Categories Groovy types gs.map({}); gs.set(); gs.range(1, 5); gs.date(); gs.regExp(); gs.stringBuffer(); … Groovy list functions added to js lists Added some functions to numbers and strings (1).times(function () {}); “Groovy”.startsWith(); “Hello”.replaceAll(); Added curry to functions Convert objects ‘to groovy’ or ‘to javascript’ gs.toGroovy(javaScriptList, NameClass); gs.toJavascript(myGroovyObject); Operators Groovy truth equals getters and setters Conversions gs.toGroovy(obj, Type); gs.toJavascript();
  14. 14. Limitations Groovy / Java not fully supported Working in groovy-core No good support for inheritance (super) No methods with same name Basic support in metaClass No packages, no classes with same name No metainfo, expandoMetaClass, … Only AST transformations applied in semantic phase No complex Java / Groovy types (LinkedList,…) … see documentation for more info on grooscript.org
  15. 15. Directly convert code @Grab(‘org.grooscript:grooscript:0.5’) ! import org.grooscript.GrooScript ! //Convert a fragment code String jsResult = GrooScript.convert(“println ‘Hello!’”) ! //Convert some file or folder, generate .js files with same name GrooScript.convert(‘path/to/file.groovy’, ‘destination/folder’) GrooScript.convert(‘path/to/folder’, ‘destination/folder’) GrooScript.convert(listOfFilesAndOrFolders, ‘destination/folder’)
  16. 16. Conversion options convertDependencies - boolean - default true classPath - List<String> or String - default null - Ex: ‘src/groovy’ customization - Closure - default null mainContextScope - List<String> - default null initialText / finalText - String - default null recursive - boolean - default false //Set a conversion property GrooScript.setConversionProperty(‘convertDependencies’, false) GrooScript.setConversionProperty(‘customization’, { ast(TypeChecked) })
  17. 17. Convert dependencies option Car.groovy Wheel.groovy Car.js convert == option wheel code included
  18. 18. Main context scope Customization • Requires Groovy 2.1, the closure is passed to withConfig(conf) • More info in http://docs.codehaus.org/display/GROOVY/Advanced+compiler+configuration • Sometimes you don’t know where to find a variable • When conversion is done, some variables come from other contexts • grooscript.js sometimes tries to find missed variables with eval • Node.js eval not working same way that browsers do • You can define variables or function names with this option • Ex. [‘$’, ‘myAwesomeFunction’, ‘myMissedVariable’]
  19. 19. Feature: Annotations @GsNotConvert @GsNative
  20. 20. Feature: Daemon
  21. 21. >phantomjs myTest.js Inject grooscript.js and jquery Use Groovy script abilities I want to be Groovy @AST http://phantomjs.org/ Please code in Groovy!
  22. 22. Mandatory Screen capture Before start test More console info Accept basic parameters Works fine in GroovyTestCase Not so well in Spock Have to define Phantom.js path Feature: PhantomJsTest
  23. 23. Example @GrabConfig(systemClassLoader = true) @Grab(‘org.grooscript:grooscript:0.5’) ! import org.grooscript.asts.PhantomJsTest ! //Need phantoms installed System.setProperty(‘PHANTOMJS_HOME’, ‘path/to/phantomjs’) ! @PhantomJsTest(url = ‘http://www.grails.org’) void grailsSiteChecks() { assert $(‘a’).size() > 50, “Not enough links ${$(‘a’).size()}” def title = $(“title”) assert title[0].text == ‘Grails - The search is over.’ $(‘a’).each { println it } } ! //Run phantomjs test grailsSiteChecks()
  24. 24. package org.grooscript.builder ! class HtmlBuilder { ! String html ! static String build(@DelegatesTo(HtmlBuilder) Closure closure) { def mc = new ExpandoMetaClass(HtmlBuilder, false, true) mc.initialize() def builder = new HtmlBuilder() builder.metaClass = mc closure.delegate = builder closure() ! builder.html } ! def yield(String text) { html += text } ! def methodMissing(String name, args) { … } } Feature: html builder def result = HtmlBuilder.build { body { ul(class: 'list', id: 'mainList') { 2.times { number -> li number + 'Hello!' } } } } ! assert result == ‘<body><ul class='list' id='mainList'><li>0Hello!</li><li>1Hello!</ li></ul></body>’ grooscript-builder.js
  25. 25. Feature: jquery tools package org.grooscript.jquery ! interface GQuery { def bind(String selector, target, String nameProperty) def bind(String selector, target, String nameProperty, Closure closure) boolean existsId(String id) boolean existsName(String name) boolean existsGroup(String name) void bindEvent(String id, String name, Closure func) void doRemoteCall(String url, String type, params, Closure onSuccess, Closure onFailure) void doRemoteCall(String url, String type, params, Closure onSuccess, Closure onFailure, objectResult) void onReady(Closure func) void html(String selector, String text) } import org.grooscript.jquery ! GQuery gQuery = new GQueryImpl() gQueryImpl.js
  26. 26. Feature: binder grooscript-binder.js package org.grooscript.jquery ! class Binder { ! GQuery gQuery = new GQueryImpl() ! def bindAllProperties(target, closure = null) { target.properties.each { name, value -> if (gQuery.existsId(name)) { gQuery.bind("#$name", target, name, closure) } if (gQuery.existsName(name)) { gQuery.bind("[name='$name']", target, name, closure) } if (gQuery.existsGroup(name)) { gQuery.bind("input:radio[name=${name}]", target, name, closure) } } } ! def bindAllMethods(target) { target.metaClass.methods.each { method -> if (method.name.endsWith('Click')) { def shortName = method.name.substring(0, method.name.length() - 5) if (gQuery.existsId(shortName)) { gQuery.bindEvent(shortName, 'click', target.&"${method.name}") } } } } ! def call(target, closure = null) { bindAllProperties(target, closure) bindAllMethods(target) } } Bind an instance properties to input elements, by Id or name Bind on click events to an instance methods new Binder()(myInstance)
  27. 27. grooscript-binder.js grooscript.js grooscript.min.js grooscript-builder.js grooscript-all.js gQueryImpl.js inside the jar, servlet 3.0: META-INF/resources http://grooscript.org/downloads.html
  28. 28. Websockets with Vert.x https://github.com/chiquitinxx/demoGroovyMeteor http://www.meteor.com https://vimeo.com/59395085
  29. 29. https://github.com/chiquitinxx/grooscript-vertx-plugin http://www.grails.org/plugin/grooscript-vertx v 0.4
  30. 30. Grooscript Vert.x Plugin Convert Groovy code to Javascript Run conversion daemon Websockets Eventbus bridge New port open Events in the client Auto reload pages Both are optional http://grooscript.org/pluginManual/ v 1.3.1 Requires Java 1.7
  31. 31. Differences?Renders on server Renders on the client Conversions are cached with cache plugin Grooscript tags auto - import js files needed
  32. 32. Grails port 8080 Vert.x port 8085 Browser gsp eventBus http websockets Config.groovy BootStrap.groovy Chat sample main.gsp
  33. 33. More eventsHtml Builder Where Listen events Render on load Send event message = println Execute on event message Don’t use ${} in grooscript tags Strong dependency Resources plugin Can put code in a .groovy file
  34. 34. Domain classes in the client* *Experimental, it requires Groovy 2.1 (grails 2.3) • validate, clientValidations ** • hasErrors • count • list * without params • get • save * without params • delete
  35. 35. Domain classes connected with the server* *Experimental, it requires Groovy 2.1 (grails 2.3) • list • get • save • delete
  36. 36. PhantomJs Tests* *Not working in Grails 2.3, need improvements New test phase phantomjs Tests in test/phantomjs More features
  37. 37. features, features… next release - new plugin - remove vert.x From resources plugin to Require.js or Asset pipeline plugin Improve domain options PhantomJs tests improvements Move to websockets/sockJs/stomp with Spring 4 in grails 2.4 and many more… Remote domain class to grails REST support
  38. 38. https://github.com/chiquitinxx/grooscript-gradle-plugin v 0.3
  39. 39. Gradle plugin Add in your build.gradle http://grooscript.wordpress.com/2014/02/22/starting-with-grooscript/ buildscript { repositories { mavenCentral() } dependencies { classpath 'org.grooscript:grooscript-gradle-plugin:0.3' } } ! apply plugin: 'grooscript' ! //If you need to change any conversion option, can do this way, optional grooscript { source = [‘src/main/groovy/presenters'] }
  40. 40. Create more conversion tasks: http://grooscript.wordpress.com/2014/01/31/61/ Converted files destination Require.js setup file Files to be converted
  41. 41. Demo springboot http://projects.spring.io/spring-boot/ REST - Require.js - Grooscript Gradle Plugin - Websockets - Mongo https://github.com/chiquitinxx/springboot-rest-demo
  42. 42. https://github.com/chiquitinxx/grooscript/tree/master/npm
  43. 43. Example using node.js colors npm module Node.js is very fast! http://grooscript.wordpress.com/2014/01/10/impressive-node-js-v8-speed/ https://github.com/chiquitinxx/colors
  44. 44. Final topics
  45. 45. Why would I use grooscript? • Create small modules to use in your views • You can continue developing in Groovy • Can use dsl’s, typeCheck, AST’s,… in the browser • You have all the java tools and IDE’s • You can work with new Javascript tools from Groovy • Don’t repeat code in two languages • Single development environment • Create your own architecture in Groovy • Don’t learn another “to Javascript” tool
  46. 46. Community will decide Future Version 0.5, you can improve I will continue improving grooscript Never will support full Groovy / Java I’m learning a lot, very fun New grails plugin in summer Focus next version: more and better java and groovy support
  47. 47. Questions?
  48. 48. Thank you! All people reading this 680 motivation clicks Jetbrains for IntelliJ IDEA v13 open source license Special thanks to René, @glaforge @marioggar @CedricChampeau @burtbeckwith

×