Il linguaggio JavaScript
 

React/Flux - Backbone - Router - Unit Testing

Jeff 19 Feb 2015 12:38
Ciao a tutti,


stiamo iniziando ad implementare una SPA che si interfaccia con un
backend che espone API REST.

Per il frontend abbiam scelto di usare ReactJs e volevamo implementare il
tutto seguendo il pattern FLUX (chiaro ma non chiarissimo).

L'utilizzo di browserify ci permette di modularizzare il tutto meglio
almeno nel frontend e di utilizzare gran parte degli npm disponibili
(nota di colore: sono stato quasi scarnificato vivo quando ho proposto di
passare a nodejs come backend)


La prima domanda a chi e' piu esperto di me e' se abbia senso utilizzare
backbone (model/collections) negli store perche' ho letto molte opinioni
contrastanti perche' si espongono gli store ad essere modificati
direttamente senza passare dal dispatcher



Per il routing avete qualche suggerimento? a parte il router di backbone
ho trovato molto interessante react-router


Cosa utlizzate per unit test?


Come ciclo di sviluppo abbiam pensato a qualcosa del genere

1 folder con jsx
2 jsx --watch compila dentro al folder js
3 watchify compila --debug in app-debug.js
4 app-debug.js viene incluso dentro index-debug.html

per il rilascio

1 browserify compila il folder js
2 uglify minimizza il tutto
3 include dentro index.html il js minimizzato

che ne pensate, puo' essere migliorato/ottimizzato/rivoluzionato?








--
Jeff
Andrea Scartabelli 20 Feb 2015 10:41
On 19/02/15 12:38, Jeff wrote:
> Per il frontend abbiam scelto di usare ReactJs e volevamo implementare il
> tutto seguendo il pattern FLUX (chiaro ma non chiarissimo).
>
> L'utilizzo di browserify ci permette di modularizzare il tutto meglio
> almeno nel frontend e di utilizzare gran parte degli npm disponibili
> (nota di colore: sono stato quasi scarnificato vivo quando ho proposto di
> passare a nodejs come backend)

Il buon Zer0 mi consigliò di buttarci un occhio tempo addietro e non ho
ancora iniziato a metterci mano seriamente, ma son d'accordo con te: per
quel che vedo Flux + React è la combinazione più interessante e promettente.

Sempre Zer0 mi ha fatto notare anche questo, che magari può
interessarti: <http://facebook.github.io/immutable-js/>

Sembra che Facebook stia sfornando parecchio codice js di qualità.

Riguardo all'avere uno stack "full-js", sarei curioso anche io di vedere
che grado di maturità ha raggiunto node in tal senso e prossimamente ho
intenzione di dedicarci un po' di tempo.

Feci qualche piccola ricerca a fine anno che mi ha portato a rivolgermi
a Express (<http://expressjs.com/>) per le mie prove.

Mi pare ben strutturato e "minimal" come dicono loro: facendo qualche
test al volo mi son trovato bene, tutto mi è sembrato naturale e non ho
avuto assolutamente la sensazione di essere ingabbiato dalla logica di
qualcun altro.

> La prima domanda a chi e' piu esperto di me e' se abbia senso utilizzare
> backbone (model/collections) negli store perche' ho letto molte opinioni
> contrastanti perche' si espongono gli store ad essere modificati
> direttamente senza passare dal dispatcher

Non ho ancora alcuna esperienza pratica in merito, ma a livello teorico
non mi verrebbe proprio da mischiare backbone con flux.

Flux è più che altro un pattern, backbone una libreria che implementa un
pattern diverso dal precedente.

Rimanendo nel tuo esempio a me sembrerebbe che gli store di flux
rimpiazzino prorio i model / collection di backbone.

> Per il routing avete qualche suggerimento? a parte il router di backbone
> ho trovato molto interessante react-router

No, non ho ancora suggerimenti, react-router è una delle cose che mi ero
appuntato anche io.

> Cosa utlizzate per unit test?

Io ho sempre utilizzato jasmine (<http://jasmine.github.io/), ogni tanto
con sinon sopra (<http://sinonjs.org/>).

Tanto per tirare ancora in ballo Facebook, pare interessante il loro
Jest (<http://facebook.github.io/jest/>) che gira sopra a jasmine.

> Come ciclo di sviluppo abbiam pensato a qualcosa del genere
>
> 1 folder con jsx
> 2 jsx --watch compila dentro al folder js
> 3 watchify compila --debug in app-debug.js
> 4 app-debug.js viene incluso dentro index-debug.html
>
> per il rilascio
>
> 1 browserify compila il folder js
> 2 uglify minimizza il tutto
> 3 include dentro index.html il js minimizzato
>
> che ne pensate, puo' essere migliorato/ottimizzato/rivoluzionato?

Io ti consiglierei vivamente di considerare "gulp"
(<https://www.npmjs.com/package/gulp>) come base per tutti i task.

Mi è sembrato *molto* più maneggevole del suo famoso predecessore grunt
e ci sono già "wrapper" precotti per tutto: browserify, minificazione,
source maps e chi più ne ha più ne metta.

Lavorando con gli stream è molto facile togliere un pezzo o incastrarne
un altro alla bisogna.
Jeff 20 Feb 2015 12:17
On Fri, 20 Feb 2015 10:41:23 +0100, Andrea Scartabelli scrisse:

> On 19/02/15 12:38, Jeff wrote:
>> Per il frontend abbiam scelto di usare ReactJs e volevamo implementare
>> il tutto seguendo il pattern FLUX (chiaro ma non chiarissimo).
>>
>> L'utilizzo di browserify ci permette di modularizzare il tutto meglio
>> almeno nel frontend e di utilizzare gran parte degli npm disponibili
>> (nota di colore: sono stato quasi scarnificato vivo quando ho proposto
>> di passare a nodejs come backend)
>
> Il buon Zer0 mi consigliò di buttarci un occhio tempo addietro e non ho
> ancora iniziato a metterci mano seriamente, ma son d'accordo con te: per
> quel che vedo Flux + React è la combinazione più interessante e
> promettente.

Si si lo consiglio' anche a me.
La scelta di React non e' in dubbio e' veramente potente e super
performante


> Sempre Zer0 mi ha fatto notare anche questo, che magari può
> interessarti: <http://facebook.github.io/immutable-js/>

Si lo ho visto, ma non arrivo a comprenderne la vera utilita'

> Sembra che Facebook stia sfornando parecchio codice js di qualità.
>
> Riguardo all'avere uno stack "full-js", sarei curioso anche io di vedere
> che grado di maturità ha raggiunto node in tal senso e prossimamente ho
> intenzione di dedicarci un po' di tempo.
>
> Feci qualche piccola ricerca a fine anno che mi ha portato a rivolgermi
> a Express (<http://expressjs.com/>) per le mie prove.
>
> Mi pare ben strutturato e "minimal" come dicono loro: facendo qualche
> test al volo mi son trovato bene, tutto mi è sembrato naturale e non ho
> avuto assolutamente la sensazione di essere ingabbiato dalla logica di
> qualcun altro.

Noi non abbiamo uno stack full-js (il backend che espone le API e' un
Symfony/CouchDB) ma non ha realmente impatto perche' esponendo REST e
usando Redis per cachare tutto e' piuttosto veloce.

>> La prima domanda a chi e' piu esperto di me e' se abbia senso
>> utilizzare backbone (model/collections) negli store perche' ho letto
>> molte opinioni contrastanti perche' si espongono gli store ad essere
>> modificati direttamente senza passare dal dispatcher
>
> Non ho ancora alcuna esperienza pratica in merito, ma a livello teorico
> non mi verrebbe proprio da mischiare backbone con flux.
>
> Flux è più che altro un pattern, backbone una libreria che implementa un
> pattern diverso dal precedente.
>
> Rimanendo nel tuo esempio a me sembrerebbe che gli store di flux
> rimpiazzino prorio i model / collection di backbone.

Il punto e' che i model e le collections di Backbone sono comodi, cosa
useresti come data-layer?

La nostra applicazione a livello di data e' piuttosto complessa a livello
di modelli. semplificare il tutto il piu' possibile e' gia' nell'agenda,
quindi suggerisci di usare plain js object?




>> Per il routing avete qualche suggerimento? a parte il router di
>> backbone ho trovato molto interessante react-router
>
> No, non ho ancora suggerimenti, react-router è una delle cose che mi ero
> appuntato anche io.

e react-router sia - lo ho provato ed e' molto molto valido (almeno per
il nostro prejetto) :)


>> Cosa utlizzate per unit test?
>
> Io ho sempre utilizzato jasmine (<http://jasmine.github.io/), ogni tanto
> con sinon sopra (<http://sinonjs.org/>).
>
> Tanto per tirare ancora in ballo Facebook, pare interessante il loro
> Jest (<http://facebook.github.io/jest/>) che gira sopra a jasmine.

ok - lo avevo gia' nei bookmark gli daro' una guardata!

>> Come ciclo di sviluppo abbiam pensato a qualcosa del genere
>>
>> 1 folder con jsx 2 jsx --watch compila dentro al folder js 3 watchify
>> compila --debug in app-debug.js 4 app-debug.js viene incluso dentro
>> index-debug.html
>>
>> per il rilascio
>>
>> 1 browserify compila il folder js 2 uglify minimizza il tutto 3 include
>> dentro index.html il js minimizzato
>>
>> che ne pensate, puo' essere migliorato/ottimizzato/rivoluzionato?
>
> Io ti consiglierei vivamente di considerare "gulp"
> (<https://www.npmjs.com/package/gulp>) come base per tutti i task.
>

e questa cosa cosa sarebbe? :o


--
Jeff
4ndre4 21 Feb 2015 14:35
On Friday, 20 February 2015 11:17:53 UTC, Jeff wrote:

[...]
>> Sempre Zer0 mi ha fatto notare anche questo, che magari può
>> interessarti: <http://facebook.github.io/immutable-js/>
>
> Si lo ho visto, ma non arrivo a comprenderne la vera utilita'

Be`, in generale, evitare che lo stato di un oggetto venga modificato durante
una serie di chiamate e` sempre una buona cosa, anche perche` potrebbe lasciare
l'oggetto in uno stato inconsistente se ci sono eccezioni. Ci sono scuole di
pensiero (come in Effective Java di Joshua Bloch) che vogliono che le classi
siano sempre "immutable" o la loro mutabilita` sia sempre limitata per quanto
possibile.
Andrea Scartabelli 23 Feb 2015 10:52
On 21/02/15 14:35, 4ndre4 wrote:
> On Friday, 20 February 2015 11:17:53 UTC, Jeff wrote:
>
> [...]
>>> Sempre Zer0 mi ha fatto notare anche questo, che magari può
>>> interessarti: <http://facebook.github.io/immutable-js/>
>>
>> Si lo ho visto, ma non arrivo a comprenderne la vera utilita'
>
> Be`, in generale, evitare che lo stato di un oggetto venga modificato durante
una serie di chiamate e` sempre una buona cosa, anche perche` potrebbe lasciare
l'oggetto in uno stato inconsistente se ci sono eccezioni. Ci sono scuole di
pensiero (come in Effective Java di Joshua Bloch) che vogliono che le classi
siano sempre "immutable" o la loro mutabilita` sia sempre limitata per quanto
possibile.

Anche senza tirare in ballo eccezioni, è bello sentirsi tranquilli
mandando in giro dati ad altri pezzi di programma.

Senza contare che ti invita (forza) a impostare il flusso dati in una
maniera più ordinata, sicura e meno prona a errori umani.

Altra chicca nel mezzo sono le Lazy Seq.

Jeff: credo che il readme del repository ti possa mettere sul piede
giusto per approfondire.
Jeff 23 Feb 2015 12:16
On Mon, 23 Feb 2015 10:56:13 +0100, Andrea Scartabelli scrisse:

> On 20/02/15 12:17, Jeff wrote:
>> On Fri, 20 Feb 2015 10:41:23 +0100, Andrea Scartabelli scrisse:
>
> [...]
>
>>> Sempre Zer0 mi ha fatto notare anche questo, che magari può
>>> interessarti: <http://facebook.github.io/immutable-js/>
>>
>> Si lo ho visto, ma non arrivo a comprenderne la vera utilita'
>
> Vedi risposta a "4ndre4": prova a leggere attentamente il readme: mi
> sembra un ottimo punto di partenza.
>
>
> [Flux]
>
>>>> La prima domanda a chi e' piu esperto di me e' se abbia senso
>>>> utilizzare backbone (model/collections) negli store perche' ho letto
>>>> molte opinioni contrastanti perche' si espongono gli store ad essere
>>>> modificati direttamente senza passare dal dispatcher
>>>
>>> Non ho ancora alcuna esperienza pratica in merito, ma a livello
>>> teorico non mi verrebbe proprio da mischiare backbone con flux.
>>>
>>> Flux è più che altro un pattern, backbone una libreria che implementa
>>> un pattern diverso dal precedente.
>>>
>>> Rimanendo nel tuo esempio a me sembrerebbe che gli store di flux
>>> rimpiazzino prorio i model / collection di backbone.
>>
>> Il punto e' che i model e le collections di Backbone sono comodi, cosa
>> useresti come data-layer?
>>
>> La nostra applicazione a livello di data e' piuttosto complessa a
>> livello di modelli. semplificare il tutto il piu' possibile e' gia'
>> nell'agenda, quindi suggerisci di usare plain js object?
>
> I dati saranno suppongo JSON che arrivano dal server, quindi sì.
> Poi questi dati seguiranno il flusso applicativo suggerito da Flux.
>
> Action -> Dispatcher -> Store -> View -> Ancora Action
>
> [...]

La mia domanda era leggermente diversa.
Una volta scaricati i dati dal server dove li salvo?


Intendo dire che non vorrei scaricarmi i dati dal server ogni volta che
ho bisogno di accedere allo stesso data-set, ma lo aggiornerei via JS e
aggiornerei via AJAX il dataset nel server remoto.

(Tra l'altro e' quello che fa l'esempio del ToDO list che si tiene i dati
locali dentro un array).

Quindi la mia domanda era se avete alcun suggerimento in modo da
sostituire il plain array con qualcosa di piu' alto livello (tipo
backbone model/collection dentro gli store), magari sto semplicemente
chiedendo cose senza senso ma per un applicazione che e' oltre la todo
list bisogna pensare anche come organizzare il data layer o no?

Per esempio supponiamo di avere un CMS builder, ho bisogno di avere tutti
i layout disponibili, tutti i componenti disponibili, la lista delle
pagine gia' create eccetera.

Per esempio ho la lista dei componenti devo poter accederla sia ogni
volta che la stampo, sia ogni volta che salvo la pagina (perche' se u
utente sceglie di mettere un componente in una pagina mi salvo il
riferimento, per esempio)

E' possibili che mi stia sfuggendo come fare ste cose in Flux, ma cosi' a
sentimento Flux diventa molto piu' utilie man mano che l'applicazione
diventa piu' complessa.


--
Jeff
Jeff 24 Feb 2015 12:53
On Tue, 24 Feb 2015 09:01:28 +0100, Andrea Scartabelli scrisse:

> On 23/02/15 12:16, Jeff wrote:
>> On Mon, 23 Feb 2015 10:56:13 +0100, Andrea Scartabelli scrisse:
>>
>>> On 20/02/15 12:17, Jeff wrote:
>>>> On Fri, 20 Feb 2015 10:41:23 +0100, Andrea Scartabelli scrisse:
>>>
>>> [...]
>>>
>>>>> Sempre Zer0 mi ha fatto notare anche questo, che magari può
>>>>> interessarti: <http://facebook.github.io/immutable-js/>
>>>>
>>>> Si lo ho visto, ma non arrivo a comprenderne la vera utilita'
>>>
>>> Vedi risposta a "4ndre4": prova a leggere attentamente il readme: mi
>>> sembra un ottimo punto di partenza.
>>>
>>>
>>> [Flux]
>>>
>>>>>> La prima domanda a chi e' piu esperto di me e' se abbia senso
>>>>>> utilizzare backbone (model/collections) negli store perche' ho
>>>>>> letto molte opinioni contrastanti perche' si espongono gli store ad
>>>>>> essere modificati direttamente senza passare dal dispatcher
>>>>>
>>>>> Non ho ancora alcuna esperienza pratica in merito, ma a livello
>>>>> teorico non mi verrebbe proprio da mischiare backbone con flux.
>>>>>
>>>>> Flux è più che altro un pattern, backbone una libreria che
>>>>> implementa un pattern diverso dal precedente.
>>>>>
>>>>> Rimanendo nel tuo esempio a me sembrerebbe che gli store di flux
>>>>> rimpiazzino prorio i model / collection di backbone.
>>>>
>>>> Il punto e' che i model e le collections di Backbone sono comodi,
>>>> cosa useresti come data-layer?
>>>>
>>>> La nostra applicazione a livello di data e' piuttosto complessa a
>>>> livello di modelli. semplificare il tutto il piu' possibile e' gia'
>>>> nell'agenda, quindi suggerisci di usare plain js object?
>>>
>>> I dati saranno suppongo JSON che arrivano dal server, quindi sì. Poi
>>> questi dati seguiranno il flusso applicativo suggerito da Flux.
>>>
>>> Action -> Dispatcher -> Store -> View -> Ancora Action
>>>
>>> [...]
>>
>> La mia domanda era leggermente diversa.
>> Una volta scaricati i dati dal server dove li salvo?
>
> Come dicevo nel messaggio precedente: negli store.
>

e su questo siamo daccordo :)

>> Intendo dire che non vorrei scaricarmi i dati dal server ogni volta che
>> ho bisogno di accedere allo stesso data-set, ma lo aggiornerei via JS e
>> aggiornerei via AJAX il dataset nel server remoto.
>>
>> (Tra l'altro e' quello che fa l'esempio del ToDO list che si tiene i
>> dati locali dentro un array).
>>
>> Quindi la mia domanda era se avete alcun suggerimento in modo da
>> sostituire il plain array con qualcosa di piu' alto livello (tipo
>> backbone model/collection dentro gli store), magari sto semplicemente
>> chiedendo cose senza senso ma per un applicazione che e' oltre la todo
>> list bisogna pensare anche come organizzare il data layer o no?
>
> Ripeto che non ho ancora esperienza diretta con Flux, ma a me non
> verrebbe proprio di infilare i model / collection di backbone lì in
> mezzo: c'è il grosso rischio di andare a rompere il flusso
> unidirezionale di flux (e allora tanto vale non adottarlo) in favore di
> non so quale beneficio.


E qui hai risposto al mio stesso dubbio, cioe' il rischio di spaccare il
flusso


> Io partirei da un altro punto di vista: quali funzionalità hanno questi
> model / collection di cui sentiresti la mancanza non usandoli?


getter and setter in primis poi save/isnew/haschanged, il push/pull/where
nelle collection oltre al fatto che sono diffusi quindi molti
sviluppatori gia' li conoscono.

L'altra idea e' creare l'oggetto backbone dentro allo store ed esportare
lo store come modulo non esponendo backbone (in questo modo dovrebbe
essere piu' difficile rompere il fluxo c*****izzato - [peggior battuta
dell'anno ma quanno ci vuole la citazione, ci vuole])


In verita' in prima istanza avremmo usato anche il router di backbone, ma
ora lo abbiamo cambiato con react-router [anche se l'integrazione con il
pattern flux non e' del tutto immediata]





--
Jeff
Jeff 11 Mar 2015 15:17
On Wed, 25 Feb 2015 08:46:23 +0100, Andrea Scartabelli scrisse:

> On 24/02/15 12:53, Jeff wrote:
>>>> Quindi la mia domanda era se avete alcun suggerimento in modo da
>>>> sostituire il plain array con qualcosa di piu' alto livello (tipo
>>>> backbone model/collection dentro gli store), magari sto semplicemente
>>>> chiedendo cose senza senso ma per un applicazione che e' oltre la
>>>> todo list bisogna pensare anche come organizzare il data layer o no?
>>>
>>> Ripeto che non ho ancora esperienza diretta con Flux, ma a me non
>>> verrebbe proprio di infilare i model / collection di backbone lì in
>>> mezzo: c'è il grosso rischio di andare a rompere il flusso
>>> unidirezionale di flux (e allora tanto vale non adottarlo) in favore
>>> di non so quale beneficio.
>>
>> E qui hai risposto al mio stesso dubbio, cioe' il rischio di spaccare
>> il flusso
>>
>>
>>> Io partirei da un altro punto di vista: quali funzionalità hanno
>>> questi model / collection di cui sentiresti la mancanza non usandoli?
>>
>>
>> getter and setter in primis poi save/isnew/haschanged, il
>> push/pull/where nelle collection oltre al fatto che sono diffusi
>> quindi molti sviluppatori gia' li conoscono.
>
> Be', molto di quanto nomini fa parte proprio dell'idea di modello che si
> ha nei pattern come MVC e non vedo che spazio abbiano qui.
>
> Lo store registra delle callback nel dispatcher per reagire ai
> cambiamenti dei dati: questo potrebbe essere visto come un "setter", con
> l'importante differenza che nessuno sta mettendo le mani nello store, ma
> è lui che sa come reagire in conseguenza a uno o più cambiamenti che
> possono avvenire anche in altri store.
>
> I componenti React (view) registrano callback sullo store, e questo
> potrebbe essere il "getter", ma c'è ancora una differenza: non è lo
> store a incapsulare la logica necessaria. Per questo stesso motivo mi
> sembra vada a cadere la necessità di "isNew / hasChanged" e compagnia.
>
> Il "save" non deve proprio avvenire lì (nello store), dev'essere in
> un'altra parte dell'applicazione: rivedi lo schema suggerito qui
> <http://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-
dispatcher.html>.
>
> Ho buttato un occhio ora alla documentazione di backbone, ma non ho
> notato il "pull" che nomini.
> Immagino che come il push aggiunga elementi, il pull permetta di
> estrarne un subset specifico (slice / splice) e where non è altro che un
> filtro.
>
> Queste sono operazioni generiche che si fanno sui dati; e quando non
> bastano i metodi dell'oggetto array si ricorre a funzioni generiche che
> introducano altre comodità.
>
> Vedo ad esempio che backbone ha underscore come dipendenza.
>
> Il mio punto qui era sottolineare che non è necessario implementare
> queste operazioni in un'entità monolitica come una collection di
> modelli: sono spesso e volentieri operazioni generiche che si fanno sui
> dati.
>
>> L'altra idea e' creare l'oggetto backbone dentro allo store ed
>> esportare lo store come modulo non esponendo backbone (in questo modo
>> dovrebbe essere piu' difficile rompere il fluxo c*****izzato - [peggior
>> battuta dell'anno ma quanno ci vuole la citazione, ci vuole])
>
> Vedi sopra: non ne capisco la necessità.
>
>> In verita' in prima istanza avremmo usato anche il router di backbone,
>> ma ora lo abbiamo cambiato con react-router [anche se l'integrazione
>> con il pattern flux non e' del tutto immediata]
>
> Appena mi decido a metterci mano ne discutiamo volentieri!

Ho lasciato passare un po' di tempo, abbiamo iniziato l'implementazione.

Store e backbone.
Non necessario - non lo abbiamo implementato di default, ma non e' il
male quindi lasciamo la scelta al singolo sviluppatore che ovviamente
pero' non dove spaccare il pattern FLUX.
Usiamo invece underscore.

Ma giuro che siamo rimasti esterrefatti dalla velocita' dello sviluppo
una volta digerito il pattern, molto molto piu' spedita e scorrevole di
prima (era JS/PHP a cowboy).





--
Jeff

Links
Giochi online
Dizionario sinonimi
Leggi e codici
Ricette
Testi
Webmatica
Hosting gratis
   
 

Il linguaggio JavaScript | Tutti i gruppi | it.comp.lang.javascript | Notizie e discussioni javascript | Javascript Mobile | Servizio di consultazione news.