Grooscript gr8conf

49
grooscript @grooscript http://grooscript.org Jorge Franco 0.5

description

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.

Transcript of Grooscript gr8conf

Page 1: Grooscript gr8conf

grooscript@grooscript

http://grooscript.org

Jorge Franco

0.5

Page 2: Grooscript gr8conf

About me

Developer, I love it

Lazy in english at school

Living in Madrid

Working at Osoco

Grooscript developer

@jfrancoleza

[email protected]

Page 3: Grooscript gr8conf

The players

Page 4: Grooscript gr8conf

Web developer

Leave your comfort zone

Move to the client side

Page 5: Grooscript gr8conf
Page 6: Grooscript gr8conf

Doesn’t run!

on browsers

Page 7: Grooscript gr8conf

Do something! No excuses

You can do a library, resolve issues, create a plugin, give feedback,

help other projects, … !

You will learn a lot

Page 8: Grooscript gr8conf

The wire

Page 9: Grooscript gr8conf

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?

Page 10: Grooscript gr8conf

File.groovy File.js

Conversion!Options

grooscript.js

Convert Groovy files

Page 11: Grooscript gr8conf

Groovy code

def sayHello = { -> println "Hello ${it}!" }[‘Groovy', ‘JavaScript', 'GrooScript'].each sayHello!assert [1, 2, 3].size() == 3class Amazing {}!amazing = new Amazing()amazing.metaClass.who = []amazing.metaClass.add = { who << it}!amazing.add 'Rafa Nadal'assert amazing.who.size() == 1

Page 12: Grooscript gr8conf

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

Page 13: Grooscript gr8conf

Javascript

GroovyJava

More Ja

vasc

ript fr

iendly

Types, inheritance, java 8, …

metaClass

Lists

Closures

Operators

Dsl’s

Expando

Maps

beans

methodMissing

Mixins

Categories

Traits

delegate

propertyMissing

Page 14: Grooscript gr8conf

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();

Page 15: Grooscript gr8conf

LimitationsGroovy / 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

Page 16: Grooscript gr8conf

Directly convert code

@Grab(‘org.grooscript:grooscript:0.5’)!import org.grooscript.GrooScript!//Convert a fragment codeString jsResult = GrooScript.convert(“println ‘Hello!’”)!//Convert some file or folder, generate .js files with same nameGrooScript.convert(‘path/to/file.groovy’, ‘destination/folder’)GrooScript.convert(‘path/to/folder’, ‘destination/folder’)GrooScript.convert(listOfFilesAndOrFolders, ‘destination/folder’)

Page 17: Grooscript gr8conf

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 propertyGrooScript.setConversionProperty(‘convertDependencies’, false)GrooScript.setConversionProperty(‘customization’, { ast(TypeChecked)})

Page 18: Grooscript gr8conf

Convert dependencies option

Car.groovy

Wheel.groovy

Car.jsconvert

== optionwheel code

included

Page 19: Grooscript gr8conf

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’]

Page 20: Grooscript gr8conf

Feature: Annotations

@GsNotConvert @GsNative

Page 21: Grooscript gr8conf

Feature: Daemon

Page 22: Grooscript gr8conf

>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!

Page 23: Grooscript gr8conf

Mandatory Screen capture Before start test

More console infoAccept basic parameters

Works fine in GroovyTestCaseNot so well in Spock

Have to define

Phantom.js path

Feature: PhantomJsTest

Page 24: Grooscript gr8conf

Example

@GrabConfig(systemClassLoader = true)@Grab(‘org.grooscript:grooscript:0.5’)!import org.grooscript.asts.PhantomJsTest!//Need phantoms installedSystem.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 testgrailsSiteChecks()

Page 25: Grooscript gr8conf

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

Page 26: Grooscript gr8conf

Feature: jquery toolspackage 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

Page 27: Grooscript gr8conf

Feature: binder

grooscript-binder.jspackage 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)

Page 28: Grooscript gr8conf

grooscript-binder.js

grooscript.js

grooscript.min.js

grooscript-builder.js

grooscript-all.js

gQueryImpl.js

inside the jar, servlet 3.0: META-INF/resourceshttp://grooscript.org/downloads.html

Page 29: Grooscript gr8conf

Websockets with Vert.xhttps://github.com/chiquitinxx/demoGroovyMeteor

http://www.meteor.com

https://vimeo.com/59395085

Page 30: Grooscript gr8conf

https://github.com/chiquitinxx/grooscript-vertx-plugin

http://www.grails.org/plugin/grooscript-vertx

v 0.4

Page 31: Grooscript gr8conf

Grooscript Vert.x Plugin

Convert Groovy code to Javascript

Run conversion daemon

Websockets

Eventbus bridge

New port openEvents in the client

Auto reload pages

Both are optional

http://grooscript.org/pluginManual/

v 1.3.1

Requires Java 1.7

Page 32: Grooscript gr8conf

Differences?Renders on server

Renders on the client

Conversions are cached with cache plugin

Grooscript tags auto - import js files needed

Page 33: Grooscript gr8conf

Grails port 8080

Vert.x port 8085

Browser gsp

eventBus

http

websockets

Config.groovy

BootStrap.groovy Chat sample

main.gsp

Page 34: Grooscript gr8conf

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

Page 35: Grooscript gr8conf

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

Page 36: Grooscript gr8conf

Domain classes connected with the server**Experimental, it requires Groovy 2.1 (grails 2.3)

• list • get • save • delete

Page 37: Grooscript gr8conf

PhantomJs Tests**Not working in Grails 2.3, need improvements

New test phase phantomjs

Tests in test/phantomjs

More features

Page 38: Grooscript gr8conf

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

Page 39: Grooscript gr8conf

https://github.com/chiquitinxx/grooscript-gradle-plugin

v 0.3

Page 40: Grooscript gr8conf

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, optionalgrooscript { source = [‘src/main/groovy/presenters']}

Page 41: Grooscript gr8conf

Create more conversion tasks: http://grooscript.wordpress.com/2014/01/31/61/

Converted files destination

Require.js setup file

Files to be converted

Page 42: Grooscript gr8conf

Demo springboot

http://projects.spring.io/spring-boot/

REST - Require.js - Grooscript Gradle Plugin - Websockets - Mongo

https://github.com/chiquitinxx/springboot-rest-demo

Page 43: Grooscript gr8conf

https://github.com/chiquitinxx/grooscript/tree/master/npm

Page 44: Grooscript gr8conf

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

Page 45: Grooscript gr8conf

Final topics

Page 46: Grooscript gr8conf

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

Page 47: Grooscript gr8conf

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

Page 48: Grooscript gr8conf

Questions?

Page 49: Grooscript gr8conf

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