Google Closure visto da vicino
             Davide Ficano

        davide.ficano@gmail.com


      GTUG, Palermo, Gennaio, 2010
Google, API e licenze
●   Ogni applicazione rilasciata da Google e'
    accessibile tramite API

●   Quasi tutte le applicazioni dispongono di API
    pubbliche e documentate

●   Le API generalmente non hanno licenze open
    source
Google Closure
Nel Novembre 2009 Google presenta Closure

●   E' Open Source (Apache license 2.0)

●   Contiene gli stessi strumenti utilizzati per
    sviluppare le applicazioni Google
Cosa fa Closure
Lo sviluppo di applicazioni Enterprise lato client rende
difficoltoso

●   gestire la dipendenza tra moduli JS
●   ottimizzare il codice prodotto
●   gestire la generazione dinamica delle pagine
Quali strumenti
Closure e' composto da tre elementi, ognuno dei
quali e' utilizzabile indipendente dall'altro

●   Closure Library
●   Closure Compiler
●   Closure Template
Closure Library
             Javascript Standard Library
Il sogno di una STL/JDK anche per Javascript

●   Concentrare le energie sullo sviluppo dell'applicazione e
    non sui task ripetitivi

●   Server agnostic, deploy della libreria in modo semplice

●   Cross browser compatibile, sempre lo stesso problema
Closure Library
                    cosa contiene
Contiene centinaia di classi che coprono le piu' disparate
aree

●   goog.dom.*
●   goog.json.*
●   goog.css.*
●   goog.net.*
●   goog.graphics.* (HTML5 canvas)
Closure Library
                  il valore aggiunto
Il considerevole numero di classi fornite è
paradossalmente l'elemento meno interessante di
Closure Library.

Il vero valore aggiunto è dato da

 ● Alta leggibilità del codice scritto
 ● Alta integrabilità con IDE

 ● Documentazione ed esempi disponibili



 ● Inclusione dinamica delle sole classi referenziate
 ● Controllo delle dipendenze tra script
Closure Library
                            Inclusione dinamica
                                            base.js

  ● Ogni applicazione deve includere via tag <script/>
    soltanto il file base.js
  ●
    base.js rende disponibili due metodi(*)
    ● goog.require(name)

    ● goog.provide(name)




(*) Comprende anche altri metodi la cui trattazione non risulta pertinente in questo contesto
Closure Library
                        goog.require()
 
goog.require('goog.dom');
 
                                                   hello.js
 function createHello() {
   goog.dom.createDom('h1', {
         'style': 'background-color:#EEE'},
         'Hello world!');
 }


<html>
    <head>
                                                       hello.html
        <script src="closure/goog/base.js"></script> 
    
        <script src="hello.js"></script>
    </head>
    <body onload="createHello()">
    </body>
 
</html>
Closure Library
                           goog.provide()

// Presenti in dom.js
                                          Le classi definite in dom.js
 
goog.provide('goog.dom');
                                          Vengono dichiarate tramite provide
  
goog.provide('goog.dom.DomHelper');
   
goog.provide('goog.dom.NodeType');


goog.require('goog.array');
 
...
  
...
                                         Le classi da cui dom.js dipende
   
goog.require('goog.userAgent');      Vengono dichiarate tramite require


goog.dom.getDocument = function() { 
  return document; 
};
Closure Library
                  Gestione dipendenze
                              deps.js

● base.js “carica” il file deps.js che contiene la lista di tutte
  le dipendenze presenti in Library
● deps.js contiene il mapping tra nome modulo e nome

  file, le classi che fornisce e le classi da cui dipende


// require('goog.dom')


goog.addDependency('dom/dom.js',            // percorso file    

   ['goog.dom', ..., 'goog.dom.NodeType'],   // classi fornite
   ['goog.array', ..., 'goog.userAgent']);   // classi richieste
Closure Library
      Gestione dipendenze per i propri file
                         calcdeps.py

La scrittura di propri moduli conformi a Closure Library
richiede la creazione di un proprio “deps.js”

Nei file della distribuzione di Library e' presente lo script
Python calcdeps.py

calcdeps.py fa il parsing dei file sorgenti alla ricerca delle
dichiarazioni goog.require()/goog.provide() e crea un file
con l'albero delle dipendenze
Closure Library
               documentazione e testing
Al suo interno Library usa strumenti diventati uno
standard de facto nella comunità Javascript.

●   JSDoc - http://code.google.com/p/jsdoc-toolkit/

●   JSUnit - http://www.jsunit.net/
Closure Compiler
                   Cosa non fa

●   Non produce codice macchina!

                     Cosa fa

● Ottimizza il codice
● Segnala errori e warning

● Analizza le dipendenze “at compile time”

● Offre strumenti di debug e test
Closure Compiler
                       come usarlo
E' possibile usare Compiler tramite

 ●   Applicazione Java a linea di comando
     Facilita l'automazione di build process

 ●   Applicazione web
     http://closure-compiler.appspot.com/home

 ●   API RESTful
Closure Compiler
                          ottimizzazioni
Sono disponibili tre livelli di ottimizzazione.
Ogni livello comprende le ottimizzazioni dei livelli inferiori

 1.WHITESPACE_ONLY
      Elimina gli spazi e gli “a capo”
 2.SIMPLE_OPTIMIZATIONS
      Il default, rinomina variabili locali e funzioni con nomi “corti”
 3.ADVANCED_OPTIMIZATIONS
     Effettua l'inline delle funzioni, molto aggressivo può produrre
  codice non funzionante se non si rispettano alcuni vincoli
Closure Compiler
SIMPLE_OPTIMIZATIONS
Closure Compiler
ADVANCED_OPTIMIZATIONS
Closure Compiler
     Alla fiera delle follie dell'ottimizzatore 1
Si supponga di avere il costruttore
function ctor() {
   
 this.name = "";

}



Utilizzando il livello di ottimizzazione Simple tutto va bene

Utilizzando il livello Advanced invece...
Closure Compiler
     Alla fiera delle follie dell'ottimizzatore 1
… si ottiene un warning sull'uso globale di this.

Per compilare senza warning e' necessario dire, tramite
JSDoc, che la funzione e' un costruttore

/**
    * @constructor
    */

function ctor() {
    
 this.name = "";
 
}
Closure Compiler
    Alla fiera delle follie dell'ottimizzatore 2
Si supponga di avere il seguente frammento di codice


alert(typeof f); // print "undefined"

var f = function (){};



Utilizzando il livello di ottimizzazione Simple il codice
rimane inalterato

Utilizzando il livello Advanced invece...
Closure Compiler
    Alla fiera delle follie dell'ottimizzatore 2
… il frammento di codice
alert(typeof f); // print "undefined"

var f = function (){};

Viene trasformato in

alert(typeof a); // print "function"
 
function a(){};

Contestualmente si ottiene un warning su f non definita

Viene stravolto il significato del codice originale!!!
Closure Compiler
    Alla fiera delle follie dell'ottimizzatore 3
Si supponga di avere il seguente frammento di codice

function f(a, b) {
 
 b = typeof(b) == "undefined" ? 1 : b;
  
}

f(1); // al parametro b viene dato un valore di default

Utilizzando il livello di ottimizzazione Simple il codice
generato risulta essere

function f(){}f(1);


Utilizzando il livello Advanced invece...
Closure Compiler
     Alla fiera delle follie dell'ottimizzatore 3
… si ottiene un warning sulla mancanza di un valore per
b ma non c'e' nessun codice generato

La soluzione consiste nel dire, tramite JSDoc, che b e'
opzionale

/**
   
* @param a
    
* @param {string} [b="hello"]
     
*/
 
function f(a, b) { 
}


f(1);
Closure Templates
                        Tofu e Soy
Closure Templates è un sistema di templating che facilita
la scrittura di elementi di interfaccia utente dinamici

 ●   Nasce per creare frammenti di elementi grafici invece
     di monolitici template per pagina

 ●   “A tool, not a framework” come riportato nella
     documentazione ufficiale; "coabita" insieme ad altri
     ambienti, librerie e framework

 ●   La sintassi del linguaggio SOY è semplice ed intuitiva
     e comprende i comuni costrutti di un linguaggio;
     iterazione, espressioni condizionali
Closure Templates
                         Tofu e Soy
●   Lo stesso template può essere utilizzato sia lato client
    che server (Java)

●   I templates vengono compilati in codice Javascript
    efficiente (SoyToJsSrcCompiler / SoyParseInfoGenerator )
●   Nessuna dipendenza da Compiler e Library,
    l'integrazione con Library va esplicitamente attivata in
    fase di compilazione (shouldProvideRequireSoyNamespaces)
●   Estendibile tramite plugin Java (come una tag library)
Closure Templates
                       Un esempio

/**
  * Greets a person using "Hello" by default. 

  * @param name The name of the person. 

  * @param? greetingWord Optional greeting word to
  * use instead of "Hello".
  */
  
{template .helloName}
     {if not $greetingWord}
        Hello {$name}!
     {else} 
    
        {$greetingWord} {$name}!
     {/if}
  {/template}
Tools
                  Integrazione Firebug
●   Closure Inspector viene utilizzata per debug e test
    integration.
    ● Attraverso dei file di source mapping (generati con

      Compiler) permette di fare debug partendo dal codice
      compilato
    ● Mostra un migliore stack trace

    ● Eseguendo le unit test mostra le assert che falliscono



●   Page Speed viene utilizzata per misurare tempi di
    risposta di una pagina
    ● Fornisce indicazioni su come ottimizzare la pagina
Conclusioni


    Pro

   Contro
Conclusioni
                             Pro
●   E' Open Source

●   E' una libreria Javascript scritta da programmatori Java
    ● package razionali e con bassa interdipendenza



●   Documentazione e supporto

●   Incoraggia l'utilizzo di good software engineering
    practices
    ● Documentare con JSDoc

    ● Scrivere test unit con JSUnit



●   Closure Compiler generalmente migliore di YUI
    Compressor
Conclusioni
                           Contro
●   E' una libreria Javascript scritta da programmatori Java

●   A discapito del nome, le closure Javascript sono
    sottoutilizzate (vedi Jquery)

●   Troppe operazioni command line come calcdeps.py

●   L'ottimizzazione advanced e' inutilizzabile

●   Non esiste un CSS compiler
Closure Visto Da Vicino
Closure Visto Da Vicino
Closure Visto Da Vicino

Closure Visto Da Vicino

  • 1.
    Google Closure vistoda vicino Davide Ficano davide.ficano@gmail.com GTUG, Palermo, Gennaio, 2010
  • 2.
    Google, API elicenze ● Ogni applicazione rilasciata da Google e' accessibile tramite API ● Quasi tutte le applicazioni dispongono di API pubbliche e documentate ● Le API generalmente non hanno licenze open source
  • 3.
    Google Closure Nel Novembre2009 Google presenta Closure ● E' Open Source (Apache license 2.0) ● Contiene gli stessi strumenti utilizzati per sviluppare le applicazioni Google
  • 4.
    Cosa fa Closure Losviluppo di applicazioni Enterprise lato client rende difficoltoso ● gestire la dipendenza tra moduli JS ● ottimizzare il codice prodotto ● gestire la generazione dinamica delle pagine
  • 5.
    Quali strumenti Closure e'composto da tre elementi, ognuno dei quali e' utilizzabile indipendente dall'altro ● Closure Library ● Closure Compiler ● Closure Template
  • 6.
    Closure Library Javascript Standard Library Il sogno di una STL/JDK anche per Javascript ● Concentrare le energie sullo sviluppo dell'applicazione e non sui task ripetitivi ● Server agnostic, deploy della libreria in modo semplice ● Cross browser compatibile, sempre lo stesso problema
  • 7.
    Closure Library cosa contiene Contiene centinaia di classi che coprono le piu' disparate aree ● goog.dom.* ● goog.json.* ● goog.css.* ● goog.net.* ● goog.graphics.* (HTML5 canvas)
  • 8.
    Closure Library il valore aggiunto Il considerevole numero di classi fornite è paradossalmente l'elemento meno interessante di Closure Library. Il vero valore aggiunto è dato da ● Alta leggibilità del codice scritto ● Alta integrabilità con IDE ● Documentazione ed esempi disponibili ● Inclusione dinamica delle sole classi referenziate ● Controllo delle dipendenze tra script
  • 9.
    Closure Library Inclusione dinamica base.js ● Ogni applicazione deve includere via tag <script/> soltanto il file base.js ● base.js rende disponibili due metodi(*) ● goog.require(name) ● goog.provide(name) (*) Comprende anche altri metodi la cui trattazione non risulta pertinente in questo contesto
  • 10.
    Closure Library goog.require() 
goog.require('goog.dom'); 
 hello.js function createHello() { goog.dom.createDom('h1', { 'style': 'background-color:#EEE'}, 'Hello world!'); } 
<html> <head> hello.html <script src="closure/goog/base.js"></script> 
     <script src="hello.js"></script> </head> <body onload="createHello()"> </body> 
</html>
  • 11.
    Closure Library goog.provide() 
// Presenti in dom.js Le classi definite in dom.js 
goog.provide('goog.dom'); Vengono dichiarate tramite provide 
goog.provide('goog.dom.DomHelper'); 
goog.provide('goog.dom.NodeType'); 
goog.require('goog.array'); 
... 
... Le classi da cui dom.js dipende 
goog.require('goog.userAgent'); Vengono dichiarate tramite require 
goog.dom.getDocument = function() { 
  return document; 
};
  • 12.
    Closure Library Gestione dipendenze deps.js ● base.js “carica” il file deps.js che contiene la lista di tutte le dipendenze presenti in Library ● deps.js contiene il mapping tra nome modulo e nome file, le classi che fornisce e le classi da cui dipende 
// require('goog.dom') 
goog.addDependency('dom/dom.js', // percorso file 
   ['goog.dom', ..., 'goog.dom.NodeType'], // classi fornite ['goog.array', ..., 'goog.userAgent']); // classi richieste
  • 13.
    Closure Library Gestione dipendenze per i propri file calcdeps.py La scrittura di propri moduli conformi a Closure Library richiede la creazione di un proprio “deps.js” Nei file della distribuzione di Library e' presente lo script Python calcdeps.py calcdeps.py fa il parsing dei file sorgenti alla ricerca delle dichiarazioni goog.require()/goog.provide() e crea un file con l'albero delle dipendenze
  • 14.
    Closure Library documentazione e testing Al suo interno Library usa strumenti diventati uno standard de facto nella comunità Javascript. ● JSDoc - http://code.google.com/p/jsdoc-toolkit/ ● JSUnit - http://www.jsunit.net/
  • 15.
    Closure Compiler Cosa non fa ● Non produce codice macchina! Cosa fa ● Ottimizza il codice ● Segnala errori e warning ● Analizza le dipendenze “at compile time” ● Offre strumenti di debug e test
  • 16.
    Closure Compiler come usarlo E' possibile usare Compiler tramite ● Applicazione Java a linea di comando Facilita l'automazione di build process ● Applicazione web http://closure-compiler.appspot.com/home ● API RESTful
  • 17.
    Closure Compiler ottimizzazioni Sono disponibili tre livelli di ottimizzazione. Ogni livello comprende le ottimizzazioni dei livelli inferiori 1.WHITESPACE_ONLY Elimina gli spazi e gli “a capo” 2.SIMPLE_OPTIMIZATIONS Il default, rinomina variabili locali e funzioni con nomi “corti” 3.ADVANCED_OPTIMIZATIONS Effettua l'inline delle funzioni, molto aggressivo può produrre codice non funzionante se non si rispettano alcuni vincoli
  • 18.
  • 19.
  • 20.
    Closure Compiler Alla fiera delle follie dell'ottimizzatore 1 Si supponga di avere il costruttore function ctor() { 
 this.name = ""; 
} Utilizzando il livello di ottimizzazione Simple tutto va bene Utilizzando il livello Advanced invece...
  • 21.
    Closure Compiler Alla fiera delle follie dell'ottimizzatore 1 … si ottiene un warning sull'uso globale di this. Per compilare senza warning e' necessario dire, tramite JSDoc, che la funzione e' un costruttore /** * @constructor */ 
function ctor() { 
 this.name = ""; 
}
  • 22.
    Closure Compiler Alla fiera delle follie dell'ottimizzatore 2 Si supponga di avere il seguente frammento di codice alert(typeof f); // print "undefined" 
var f = function (){}; Utilizzando il livello di ottimizzazione Simple il codice rimane inalterato Utilizzando il livello Advanced invece...
  • 23.
    Closure Compiler Alla fiera delle follie dell'ottimizzatore 2 … il frammento di codice alert(typeof f); // print "undefined" 
var f = function (){}; Viene trasformato in 
alert(typeof a); // print "function" 
function a(){}; Contestualmente si ottiene un warning su f non definita Viene stravolto il significato del codice originale!!!
  • 24.
    Closure Compiler Alla fiera delle follie dell'ottimizzatore 3 Si supponga di avere il seguente frammento di codice 
function f(a, b) { 
 b = typeof(b) == "undefined" ? 1 : b; 
} f(1); // al parametro b viene dato un valore di default Utilizzando il livello di ottimizzazione Simple il codice generato risulta essere function f(){}f(1); Utilizzando il livello Advanced invece...
  • 25.
    Closure Compiler Alla fiera delle follie dell'ottimizzatore 3 … si ottiene un warning sulla mancanza di un valore per b ma non c'e' nessun codice generato La soluzione consiste nel dire, tramite JSDoc, che b e' opzionale 
/** 
* @param a 
* @param {string} [b="hello"] 
*/ 
function f(a, b) { 
} 
f(1);
  • 26.
    Closure Templates Tofu e Soy Closure Templates è un sistema di templating che facilita la scrittura di elementi di interfaccia utente dinamici ● Nasce per creare frammenti di elementi grafici invece di monolitici template per pagina ● “A tool, not a framework” come riportato nella documentazione ufficiale; "coabita" insieme ad altri ambienti, librerie e framework ● La sintassi del linguaggio SOY è semplice ed intuitiva e comprende i comuni costrutti di un linguaggio; iterazione, espressioni condizionali
  • 27.
    Closure Templates Tofu e Soy ● Lo stesso template può essere utilizzato sia lato client che server (Java) ● I templates vengono compilati in codice Javascript efficiente (SoyToJsSrcCompiler / SoyParseInfoGenerator ) ● Nessuna dipendenza da Compiler e Library, l'integrazione con Library va esplicitamente attivata in fase di compilazione (shouldProvideRequireSoyNamespaces) ● Estendibile tramite plugin Java (come una tag library)
  • 28.
    Closure Templates Un esempio 
/** * Greets a person using "Hello" by default. 
  * @param name The name of the person. 
  * @param? greetingWord Optional greeting word to  * use instead of "Hello". */ 
{template .helloName} {if not $greetingWord} Hello {$name}! {else} 
     {$greetingWord} {$name}! {/if} {/template}
  • 29.
    Tools Integrazione Firebug ● Closure Inspector viene utilizzata per debug e test integration. ● Attraverso dei file di source mapping (generati con Compiler) permette di fare debug partendo dal codice compilato ● Mostra un migliore stack trace ● Eseguendo le unit test mostra le assert che falliscono ● Page Speed viene utilizzata per misurare tempi di risposta di una pagina ● Fornisce indicazioni su come ottimizzare la pagina
  • 30.
    Conclusioni Pro Contro
  • 31.
    Conclusioni Pro ● E' Open Source ● E' una libreria Javascript scritta da programmatori Java ● package razionali e con bassa interdipendenza ● Documentazione e supporto ● Incoraggia l'utilizzo di good software engineering practices ● Documentare con JSDoc ● Scrivere test unit con JSUnit ● Closure Compiler generalmente migliore di YUI Compressor
  • 32.
    Conclusioni Contro ● E' una libreria Javascript scritta da programmatori Java ● A discapito del nome, le closure Javascript sono sottoutilizzate (vedi Jquery) ● Troppe operazioni command line come calcdeps.py ● L'ottimizzazione advanced e' inutilizzabile ● Non esiste un CSS compiler