Meteor
Esse é meu primeiro post aqui no JavascriptBrasil. Agradeço o @osuissa pelo convite (e vocês podem culpá-lo se não gostarem dos posts hehe)
Nesse primeiro post eu vou falar sobre um novo framework de Javascript chamado Meteor, que conheci em um post no Hacker News e estava na minha lista de coisas interessantes a olhar com calma.
O Meteor é um framework realmente interessante. Ele é baseado em algumas tecnologias de JavaScript que permitem criarmos um aplicativo completo usando apenas essa linguagem, tanto a porção servidor (ele usa o Nodejs para isso) quanto a parte cliente (jQuery e templates usando o Handlebars)
Para instalar o Meteor é preciso executar os comandos no terminal (no Linux e MacOSX):
curl install.meteor.com | /bin/sh
Para criar um novo projeto é só executar os comandos:
meteor create myapp
O Meteor possui um servidor para podermos fazer o teste da aplicação. Para executá-lo é só:
cd myapp
meteor
E para acessar no navegador é só usar a url http://localhost:3000
Um projeto do Meteor é composto de três arquivos: um css, um html e um JavaScript. Pode ser estruturado de outra forma, mas esse é o exemplo mais comum. Dentro do JavaScript podemos definir a lógica que será executada no cliente (e que será enviada para o navegador do usuário) e a porção que será executada no servidor (no Nodejs).
Para testar o framework eu criei um pequeno projeto, de cadastro de contatos. Para rodar o meu exemplo é só executar (depois de ter instalado o Meteor):
git clone git@github.com:eminetto/MeteorContactListSample.git
cd MeteorContactListSample/
meteor
No arquivo ContactList.html é definido o visual do aplicativo, usando o sistema de templates usado pelo Meteor. No trecho abaixo definimos dois templates (add_contact e contacts) e fazemos a inclusão dos dois, dentro da tag body:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <head> <title>ContactList</title> </head> <body> {{> add_contact}} {{> contacts}} </body> <template name="add_contact"> <h3>{{action}} contact</h3> <div id="new-contact"> <input type="hidden" id="id" name="id"> Name: <input type="text" name="name" id="name"><br> E-mail: <input type="text" name="email" id="email"><br> <input type="button" id="actionButton" value="{{action}}"> </div> </template> <template name="contacts"> <h3>Contacts</h3> <div id="contacts"> {{#each contact_list}} <div class="contact"> {{name}} - {{email}} <input type="button" class="edit" id="{{_id}}" value="edit"> <input type="button" class="del" id="{{_id}}" value="del"> <br> </div> {{/each}} </div> </template> |
O que está dentro de {{ e }} são variáveis que serão substituídas pelo sistema de templates. A instrução each é usada como um for e mostrará todos os contatos existentes.
No arquivo ContactList.js está a lógica do aplicativo. E aí entra algo muito interessante: as Collections. São interfaces para o banco de dados MongoDB que é usado pelo framework. Na documentação é citado que pode ser extendido para usar com outros bancos de dados, mas não cheguei a testar isso. Quando a aplicação é executada é criado um banco de dados MongoDB e os dados são inseridos nele. Uma das coisas mais legais do Meteor é que ele gera uma cópia do banco de dados no lado do cliente, assim o mesmo comando usado pelo servidor é usado pelo cliente. E os dados são sincronizados, o que significa que no momento que um cliente modifica o banco de dados essa mudança é replicada automaticamente para o servidor, que manda a alteração para todos os clientes. Magia negra! Você tem um sistema sincronizado entre diversos clientes, sem precisar se preocupar com isso, o que é realmente uma vantagem.
O código do ContactList.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | Contacts = new Meteor.Collection("contacts"); if (Meteor.is_client) { Session.set('action','add'); Template.add_contact.action = function () { var action = Session.get("action") || "add"; return action; }; Template.add_contact.events = { 'click input#actionButton' : function (evt) { var $action = Session.get('action'), $name = $("#name").val(), $email = $("#email").val(); console.log($action); if ($action == 'add') { Contacts.insert({ name: $name, email: $email }); alert('contact ' + $name + ' added'); } else { Contacts.update($("#id").val(), {$set: {name: $name, email: $email}}); $("#id").val(''); Session.set('action', 'add'); alert('contact ' + $name + ' modified'); } $("#name").val(''); $("#email").val(''); } }; Template.contacts.contact_list = function () { return Contacts.find({}, {sort: {name: 1}}); }; Template.contacts.events = { 'click input.del' : function (evt) { var $contact = $(evt.target), $id = $contact.attr('id'); Contacts.remove($id); }, 'click input.edit' : function (evt) { var $contact = $(evt.target), $id = $contact.attr('id'); contact = Contacts.findOne($id); $("#id").val(contact._id); $("#name").val(contact.name); $("#email").val(contact.email); $("#name").focus(); Session.set('action', 'edit'); }, }; } if (Meteor.is_server) { Meteor.startup(function () { // code to run on server at startup }); } |
No código é possível ver os comandos is_client e is_server que dividem o código do cliente e servidor (eles podem ser separados em arquivos diferentes também). Também é possível ver o sistema de eventos (Template.contacts.events) e o retorno do banco de dados sendo enviado ao template (return Contacts.find({}, {sort: {name: 1}});)
No site do Meteor existem alguns exemplos mais complexos que ajudam a entender os detalhes mais avançados.
Apesar de ser uma ferramenta nova (versão 0.3.3 no momento da escrita deste post) eu fiquei surpreso com as possibilidades que ela fornece. Não cheguei a testar em uma aplicação mais complexa ou com maior carga, mas é uma tecnologia que vou prestar muita atenção na sua evolução, pois vejo várias utilidades para ela.
Pingback: Post no Javascript Brasil « Elton Luís Minetto
Belo artigo, parabéns (;
Posso criar sites com esse framework?
Não vejo motivos para não usar
Pingback: E então JavaScript | abruno.com