Jails 2 – Release Triton

Estátua de Mármore do Deus Triton

 

 

Galera, é com muito prazer que vos informo que o Jails foi bem sucedido, e está indo para sua versão 2!


Agradecimentos

Antes de tudo queria agradecer à todos que contribuíram de alguma forma, seja por uma mensagem de confiança, seja por reply em posts sobre o assunto, dando stars no github, emails, ou mesmo usando e me dando feedbacks!

A Versão

Embora o funcionamento seja bem parecido com as outras versões, esta possui algumas mudanças significativas e por isso a necessidade de um update major no versionamento.

Um parênteses aqui, já me perguntaram sobre os codinomes. Os codinomes que escolhi são nomes de personagens da mitologia grega, as versões 0.0.x, e 0.1.x usavam nomes de heróis por serem versões mais iniciais, modestas. Esta é a primeira versão mais robusta ( por ter passado por um período de experiência ) então usa o codinome de um deus.

Mudanças

Ele está bem melhor agora e o mais surpreendente é que está menor o.O. Isso porque a grande mudança é o fato de que agora só existem Componentes. Removi completamente a necessidade de se criar as Apps Controllers.

Após alguns feedbacks, percebi que em alguns casos era difícil saber se o que estava fazendo deveria ser uma controller ou um componente. Quando era criado o componente e logo após a especificação mudava ou ele era colocado em outro contexto, era necessário usar métodos de controller que ele não possuía. Então precisava de um refactory desnecessário e mudar de componente para controller, tanto no arquivo, na pasta que ele estava e no markup.

Então, a conclusão que cheguei foi de que o melhor mesmo seria seguir pelo caminho mais correto, inclusive o caminho que grandes players estão indo, como é o caso do React, Angular2, Vue.js, o caminho dos componentes.

Consequências

A consequência direta disso é que tive de abrir mão para o fato de que os componentes agora deveriam se relacionar, e poderá existir um acoplamento maior. Como são utilizados eventos, ao remover um componente de um contexto, na prática o javascript NUNCA quebra, não dá erro já que o sistema utiliza sistema de mensagem por eventos, portanto, se alguém não grita, ninguém escuta… e isso é fantástico.

O repositório dos componentes e módulos precisou de um branch novo, pois após o upgrade da versão, os antigos não iam funcionar, então todos os componentes residem agora no branch v2. Aproveitei pra remover os que não eram usados, melhorar a performance e a documentação, dei uma enxugada.

Outra mudança que ajuda muito é o fato de que agora os componentes podem ouvir uns aos outros, não só os filhos, quanto os que estão no mesmo nível do markup.

Brasil! Mostra a sua cara!

Chega de falar de forma abstrata e vamos mostrar um pouco da cara de um componente nessa versão maravilhosa.

Vamos criar novamente um dialog, um modal com texto dinâmico, estou sem criatividade para exemplos como podem ver xD.

O html:

<div class="dialog" data-component="view modal">
    <h2>Olá <span data-value="{name}">Fulano</span>!</h2>
</div>

Olha que coisa linda do pae…

O componente de modal vai botar uma classe “open” ou removê-la, e possui os métodos públicos open() e close() olha só:

import jails from 'jails'

jails('modal', ( component, element, anno )=>{

	component.init = ()=>{}

	component.open = ()=>{
		element.classList.add('open')
	}

	component.close = ()=>{
		element.classList.remove('open')
	}

})

Dá para ver que não existe mais o jails.component agora tudo é componente, então seria redundante, o objeto Jails virou uma função. Outra diferença é que o jails possui traços ainda mais funcional do que antes.

Diferentemente das outras soluções como o React ou Angular2 que estão seguindo uma linha mais de Classes e herança, o Jails vem numa pegada um pouco mais funcional e de composição. Agora não precisa mais criar mixins usando a keyword this. Você vai decorando o objeto component que recebe.

Agora o Dialog é o componente que fará a lógica de abrir e fechar o modal de acordo com algum contexto, seja um click ou algum resultado de um feedback. Vamos fazer ele abrir via pub/sub, escutando o evento global dialog:open.

Não precisamos mais pensar em criar controllers e adicionar um wrapper pra esse div que criamos, basta inserir mais um elemento na lista de componentes:

import jails from 'jails'

jails('dialog', ( component, element, anno )=>{

	let view, modal
	
	component.init = ()=>{
		view  = component.get('[data-component*=view]')
		modal = component.get('[data-component*=modal]')
		
		component.subscribe('dialog:open', open)
		component.subscribe('dialog:close', close)
	}

	let open = ( data )=>{
		modal('open')
		view('update', data)
	}

	let close = ()=>{
		modal('close')
	}

})

Não é fabuloso? Não é simples? Não é maravilhoso?

Uma coisa que pouco se fala em conferências e palestras. Como fazer um BI desacoplado? Você costuma botar os códigos ga na lógica do seu módulo?

Eu prefiro não fazer isso, e com o Jails é mais simples e modular ainda, basta criar um componente numa pasta track/modal para todos os modais do site, e ficar escutando ou os eventos customizados de abrir e fechar, ou os próprios eventos de click no dom, se precisar.

Você pode adicionar esse tracking ou remover do data-component  no seu html. Além de organizar melhor seus arquivos, você não precisa inserir na lógica do seu módulo os trackings

Finalizando…

É isso galera, só queria compartilhar com vocês essa versão nova e minha alegria de ver que realmente funciona… a idéia toda casou completamente com a necessidade que temos na equipe que trabalho, e tem me dado muita alegria nesses últimos tempos.

É simples, se propõe a resolver pequenos problemas e esse é o diferencial dele, é muito fácil conversar com outras bibliotecas e pra mim, faz todo o sentido do mundo você conseguir compor sua aplicação com diversas bibliotecas em paralelo… é isso que não consigo ver muito bem nesses frameworks muito parrudos, você fica muito preso à um só paradigma.

Tive de atualizar toda a documentação, mas ficou muito mais simples tanto de escrevê-la como de entender o próprio micro-framework, coisa que agora vejo, não estava muito fácil antes.

Tudo o que precisam saber no caso de se interessar está aqui: https://github.com/jails-org/Jails

Ficaria muito feliz com qualquer tipo de contribuição, e ficaria mais contente se fosse tão útil para vocês quanto está sendo para mim.

Um grande abraço

Valeu!

Screencast – Controller Dialog

Galera, vai um post rápido porque já faz um tempo que o blog tá meio parado.

Fiz um screencast usando a versão mais atual do Jails, bem mais maduro, usando Webpack e o ES6. Demorou um tempo para adotar o ES6 confesso, muito mais pelo fato de esperar que os transpilers ficassem mais maduros e mais estáveis. Assim como as especificações sobre o ES6, definições do que seria o draft, quais seriam os presets etc.

É claro que aconselho usarem o ES6 assim como o Webpack, é um grande avanço principalmente para os que ainda estão um pouco parados nos paradigmas antigos.

Existe uma série de vantagens em usar o ES6 hoje, bem como ferramentas fantásticas como o Webpack, quem não conhece ou ainda não mexeu, fica a dica =).

Screencast

Esse screencast ficou um pouco longo, também percebi alguns erros depois de pronto, mas estou com muita preguiça de editar =/. Peço que ignorem os erros de português, onde falo “internalização” entenda por “internacionalização” etc.

A idéia do vídeo é mais mostrar um pouco de como é programar usando a lógica do Jails, como separar os problemas e de quebra um pouco de código em ES6. Valeu!

Jails – módulo Throwable

Fala povo!

Demorei pra postar, mas estou aí. Bom, este post é uma sequência, ele é uma continuação do anterior que trata sobre tratamento de erros no javascript.

Uma vantagem de trabalhar com algum framework é a previsibilidade que ele te dá, sendo consistente nos seus próprios padrões.

Isso te dá uma visão macro da aplicação sem ter de pensar muito e te permite criar novas soluções de forma mais rápida e objetiva. Sendo assim, com o Jails como framework,  criei um módulo bem básico e ainda beta, chamado Throwable.

Propósitos

A idéia geral deste módulo é garantir que se uma controller Jails lançar alguma excessão em produção, este irá garantir que as outras controllers continuem funcionando.

Existem outras finalidades também. O módulo Throwable também fornece uma api que facilite encapsular alguma função em try/catch caso esta função tenha algum risco de falhar, que não dependa da nossa lógica, algo externo ao nosso escopo.

O terceiro propósito é desacoplar da lógica da aplicação, detalhes de implementação no caso de algo falhar. Isso permite que sua controller fique realmente fácil de entender mais compacta e concisa.

Configuração

Para habilitar no projeto é bem simples, basta usá-lo como middleware, carregando como dependência do projeto.

require.config({
    baseUrl :'js/',
    deps    :['jails', 'throwable', global.page],
    paths   :{
        jails       :'//rawgit.com/jails-org/Jails/master/source/jails.min',
        throwable   :'//rawgit.com/jails-org/Modules/throwable/throwable'
    },
    callback :function( jails, throwable ){
        throwable({ debug :false });
        //Use true for debug
        jails.start();
    }
});

Ele simplesmente implementará o try/catch na classe controller e no método .init() dela. Só esta linha já garante que um módulo não quebre outro.

O Throwable vai fazer um bypass nos eventos de erro do browser, ou seja, você não irá mais receber erros no console, a não ser que os erros sejam de sintaxe. Erros de sintaxe não são possíveis de tratar, estou considerando que no seu processo de build, você já barre qualquer erro de sintáxe do código =).

Capturando eventos de erros globais

Como não receberá mais o alerta no console, o módulo Throwable dispara eventos dos erros capturados. Você pode dessa forma dar um console log, ou fazer uma lógica um pouco mais automatizada para mostrar os erros em produção.

define([
	'jails'
], function( jails ){

	jails.controller('minha-controller', function( html, data ){

		this.init = function(){
			this.subscribe('throwable', log);
			undefinedMethod();
		};

		function log(err){
			console.log('Erro!', err);
		}
	});
});

No caso acima, a controller se inscreve no evento throwable , que é o evento global para qualquer tipo de erro. O código vai levantar uma exceção porque existe uma função não definida sendo chamada.

Capturando erros em uma controller

É possível capturar erros lançados de uma determinada controller. Isso permite que deixemos a lógica de tratamento de erro fora da nossa controller. No script acima não fica claro a vantagem do Throwable, mas perceba a vantagem disso no script abaixo:

minha-controller.error.js

define(['jails'], function( jails ){

    jails.subscribe('throwable@controller:test', function( error ){

        switch( error.message ){

            case 'link:no-title':
                console.error('No attribute [title] was found for that link');
            break;

            default : console.error('Uncaught Error', error);
        }
    });
});

Esse é o arquivo de erro externo de tratamento de erro da controller. Ele consegue capturar os erros que vem de uma controller específica, fazendo um .subscribe em : throwable@controller:nome-da-controller.

No caso acima ele possui um comportamento padrão caso não consiga tratar o erro, apenas logando no console. Existe um erro que ele está tratando que é um link sem title. Mais adiante vou mostrar um método útil para encapsular uma função específica em um try/catch.

O método .try()

Por padrão, o throwable trata no try/catch apenas situações criticas, ou seja, a execução do mixin e a inicialização dele através do método init(). Isso porque não seria nada performático aplicar o try/catch em todos os métodos.

Então cabe a você definir onde são os pontos críticos específicos da sua aplicação. Como identificar estes pontos? Imagine uma função de soma, nunca haverá excessões, apenas erros de cálculo.

Agora numa divisão, se está recebendo duas entradas, o divisor e o dividendo, dependendo das entradas sua função poderia levantar uma excessão numa possível divisão por zero. Ou seja, você não sabe quais dados serão inputados, fatores externos à sua função podem fazer com que ela levante uma exception.

Identificado o ponto que pode levantar a exception, você pode então usar o .try() para poder encapsular um método e tratar em outro arquivo a excessão.

define([
    'jails',
    'errors/minha-controller.error'
], function( jails ){

    jails.controller('minha-controller', function( html, data ){

        this.init = function(){
            this.on('click', 'a', this.try( message ));
        };

        function message(){

            var title = this.title;

            if( title )
                alert( 'Hey, it works! The title is :' + title );

            else throw 'link:no-title';
        }
    });
});

Um exemplo bem besta e quase que inútil, mas apenas para perceber que em determinada situação, você apenas quer dizer na sua controller que aquele ponto pode lançar um erro, e o tratamento deste erro não importa para a controller.

O módulo Throwable estende a classe controller, por isso no código acima você percebe o uso de this.try(), que não existe nativamente nas controllers do Jails.

A forma como organiza os erros é por sua conta, dependendo do projeto podem existir erros recorrentes que podem ser resolvidos ou podem ser tratados de uma mesma forma. Nesta situação seria interessante criar um módulo de tratamento de erro que poderá ser reutilizado em várias controllers.

Um erro muito comum é o erro de resposta ajax. Você poderia criar um padrão para os tipos de erros, e mostrar um feedback, tanto na controller do seu módulo, ou criar uma controller de notificação como temos nos sistemas operacionais por exemplo, para avisar ao usuário de que tal operação falhou.

Este é o tipo de erro que terá de tratar em vários módulos, em várias telas, faz todo sentido do mundo tratá-los de forma independente, e deixar a lógica da sua controller apenas para as regras de negócio, para as regras da sua aplicação. Assim, qualquer problema de lógica pode ser facilmente detectado, porque sua lógica de tratamento de erros e outras coisas não irão atrapalhá-lo ao visualizar sua controller.

O módulo Throwable está pronto e documentado no repositório oficial de módulos do Jails.

https://github.com/jails-org/Modules/tree/master/throwable

Se não for útil do jeito que é, tomara que sirva pelo menos para te dar uma idéia diferente e ajudar a pensar em uma forma de como abstrai os erros em suas aplicações =).

É isso, um grande abraço.

Javascript e um Sistema Tolerante à Falhas

Sistema tolerante à falhas é uma das matérias da Ciência da Computação que eu menos gostei, ao mesmo tempo foi o que mais me chamou a atenção, porque embora fosse uma matéria muito maçante, muito baixo nível, ela tem uma visão que pode ser perfeitamente usada no front-end, no Javascript.

Javascript Exceptions

Toda vez que depara com um erro de javascript no browser significa que uma Exception foi lançada e nenhum mecanismo no seu sistema soube tratar ou capturar esta exception, no final sobra para o Browser resolver o que fazer com aquilo, geralmente é “logando” no console a mensagem de erro.

Tudo bem, pode ser que isso não seja novidade para a maioria, mas o que a gente não pára pra analisar é.

  • Como poderíamos tratar os erros no javascript
  • Como identificar os pontos do seu código que pode quebrar
  • Qual a importância disso?

Consequência de um erro não tratado

Bom, o porque de ser importante no mínimo pensar sobre o assunto é fácil de entender usando bom e velho exemplo de uma aplicação do Twitter.

Eu não conheço nada da regra de negócios da aplicação do Twitter e a abstração a seguir é apenas para ilustrar, digamos que separemos os módulos da aplicação como mostrado na imagem, numa arquitetura modular:

Screen Shot 2015-11-09 at 20.50.39

Imagine que o seu primeiro módulo, lá na barra de status no topo esquerdo quebre, ou seja, lance uma exception não tratada no momento que é iniciado. Se sua arquitetura executa os módulos de forma sequencial, isto significa que este é o primeiro módulo a ser executado e portanto, nenhum outro vai ser executado à partir deste ponto.

Ruim né? Ou seja, NADA irá funcionar e no pior das hipóteses, dependendo de como implementa o conteúdo da parte central, se esta for totalmente dependente de Javascript, ficará comprometida e totalmente em branco!!!.

Isso acontece em parte porque o Javascript é interpretado, de forma sequencial, ele não é compilado e portanto seus erros  ocorrerão em tempo de execução, a partir dali todo o resto do código é comprometido e o interpretador não sabe o que fazer com aquilo.

O que poderíamos fazer?

Eu não tenho a pretensão de ensinar você como tratar erros da melhor forma no Javascript, primeiro porque não tenho tanta competência no assunto e outra porque é extremamente subjetivo, cada caso é um caso, mas posso mostrar algumas idéias à partir de alguns pontos de STF ( Sistema Tolerante à Falha ) que aprendi, de maneira muito artificial e um pouco mais didática e prática.

Não vou usar os jargões da matéria como confiabilidade, resiliência etc etc.. isso é bem chato, eu boto um link no final para caso queiram aprofundar no assunto.

No caso do Twitter, imagina que sua arquitetura modular possui padrões, e uma delas é que o módulo sempre é iniciado através de uma chamada .init(). Já é uma pista certo? Na situação anterior, identificamos que o carregamento destes módulos é uma situação crítica, portanto precisamos tratar TODOS os possíveis erros que acontecem no momento da inicialização, essa é a segunda pista.

Então você pode pensar que isso é a coisa mais fácil de fazer, você conhece seu código, “sabe” onde pode dar bosta, certo? Claro que não.

Um módulo pode iniciar uma série de scripts, inclusive scripts de terceiro. E é aí que o perigo mora. Você conhece 100% o que o script de terceiro faz no seu código? Seja uma chamada do google analytics, seja uma biblioteca para resolver um determinado problema, você sabe todas as possíveis situações onde seu script pode quebrar?

Não, não sabe. Mas temos pistas suficientes para dizer que este é um ponto crítico, ao mesmo tempo que não sabemos exatamente que erro pode acontecer, portanto a solução poderia ser esta:

var module;

for( var i = 0, len = modules.length; i > len; i++ ){ 
    module = modules[i]; 
    try{ module.init(); }
    catch(e){ 
        myLogger.log('Erro de inicialização de módulo =>', module.name, e);
    }
}

É simples né? Resolve todos os problemas do mundo e agora seu sistema é totalmente tolerante à falhas? Lógico que não, mas esta besteirinha faz com que sua aplicação seja um pouco mais tolerante, menos frágil.

Esta pequena mudança simplesmente  garante que os outros módulos funcionem de forma independente no momento de inicialização, e se sua arquitetura é realmente modular, o usuário pode nem perceber que seu módulo de notificações está com problemas! Olha que maravilha. E tem ainda mais um ganho, muitas vezes os erros acontecem e o browser te dá esta dica:

Undefined is not a function

Na linha x, na coluna y, do script third-party, ou de uma biblioteca, tipo jQuery… e aí?

O tratamento de erro do try/catch ainda de quebra te dá uma mensagem mais amigável, dizendo exatamente quando e qual módulo quebrou, dando um mínimo de informação relevante.

Exceptions “assíncronas”

Mas você pode se perguntar do por que em alguns casos um determinado erro no seu javascript não influencia seu sistema como um todo. Sabe quando (quase) tudo está funcionando perfeitamente e você percebe que há um erro no console ?

Isso ocorre porque seu código já carregou e executou perfeitamente, porém existem erros em trechos de códigos assíncronos como um calback de um ajax, ou um evento de click por exemplo. Neste último caso, o trecho de código será executado e avaliado pelo interpretador apenas no momento do clique, é um outro “stack”, portanto não vai influenciar na inicialização dos seus módulos, mas irá influenciar todo o código posterior ao erro neste evento. Um exemplo, um caso clássico, aposto que já passou por isso alguma vez:


$('.module a').click( request );

function request(e){

    e.preventDefault();
    _gaq.push(['_trackEvent', 'name', 'some value']);

    module.get('my/service/').done( callback );
};

Quem nunca? Existem dois problemas em potencial aí neste código, o primeiro é se por algum motivo alguém remove o analytics da página, o que seria por si só um problema sério ou o google muda a api, raro acontecer sem aviso prévio, mas dependendo do script pode acontecer.

O segundo, mais frequente, é se alguem chamar o .request() de maneira independente ao invés de passar a função como parâmetro para ser usado como um handler de evento. Neste caso, não existe a variável de evento, então a chamada do e.preventDefault() não irá funcionar.

São duas práticas ruins, mas de qualquer forma, estes problemas não deveriam inutilizar seu módulo, pensando num sistema mais tolerante à falhas.

A forma mais rápida de permitir que seu sistema não fique tão frágil, seria colocar scripts de prioridade baixa pro final, porque se aquele script quebra, não vai fazer com que seu módulo pare de funcionar.

Você também não deveria colocar try/catch em todos os trechos do seu código, isso certamente em alguma situação prejudicaria tanto a manutenção e legibilidade do seu código, como também a performance da sua aplicação.

Nesse caso, desacoplar tanto o handler de evento quanto a implementação do analytics seria interessante, assim como testar se as variáveis existem.

Mas o que eu quero mostrar aqui é que há casos onde não é tão simples assim enxergar trechos sensíveis à bugs, é por isso que não existe uma fórmula de como proteger seu código, mas que vale a pena enxargá-lo com outros olhos à partir de agora.

Outra coisa importante é perceber que os erros podem ser tratados e revertidos. Por exemplo, um ajax que falha na requisição.

Você pode informar o usuário de que a ação falhou e pedir que ele tente novamente, ou em alguns casos, se percebe que existe uma certa instabilidade em um serviço, você pode fazer uma segunda tentativa de forma transparente ao usuário. Ele não vai notar que ouve um erro, dependendo de alguns fatores de conexão, pode ser até que ele mal perceba que ouve um tempo maior de espera, já que foram feitas duas requisições ou até três. Se você usa celular, provavelmente já passou por esta situação como usuário inúmeras vezes e não percebeu nada.

Abrindo a mente…

Um dos problemas que eu queria resolver no desenvolvimento das minhas aplicações é começar a me preocupar com problemas deste tipo, como melhorar a experiência do usuário e programar de forma, vamos dizer, mais profissional.

Eu não conseguia fazer isso porque a maior parte do tempo estava lutando com a arquitetura mal feita de alguma aplicação/site, ou implementando do zero um componente que já deveria estar pronto, ou perdendo tempo fazendo coisas do zero, quando deveria apenas me preocupar com problemas mais alto nível, como Tolerância à falhas.

Bom, eu havia dito num post anterior que havia conseguido melhorar minha arquitetura consideravelmente com o Jails e poderia me preocupar com outras coisas já que agora posso reutilizar mais o código. Portanto tenho tempo para pensar em melhorias como esta, ao invés de me preocupar com problemas corriqueiros.

Isto abre uma nova perspectiva sobre o que eu estou desenvolvendo e como estou desenvolvendo, abrindo novas posssibilidades.  Estou construindo um módulo chamado Throwable que se beneficia da arquitetura do Jails e automatiza o processo de lançar e tratar erros, um problema que nunca dei atenção no Javascript.

No próximo post, vou mostrar este módulo, que já deve estar numa versão mais beta e dar algumas idéias e formas diferentes de como deixar o tratamento de erros um pouco mais elegante e seu sistema mais tolerante à falhas.

Tudo o que aprendi sobre tratamento de erros no javascript, foi lendo algumas apresentações e artigos do Nicholas Zakas, um cara brilhante que se você não conhece, deveria conhecer. Ele já fala sobre arquitetura modular faz 1 milhão de anos.

Pode ignorar tudo o que escrevi, mas leia estes conteúdos sobre tratamento de erros no javascript dele, vai ganhar muito!

Sobre STF:

http://www.inf.ufrgs.br/~taisy/disciplinas/textos/ConceitosDependabilidade.PDF

http://www.cin.ufpe.br/~jvob/introducao.html

 

 

Novo release do Jails 1.0.0 e a experiência de escrever um framework

Fala meu povo!

Eu às vezes me sinto um pouco babaca escrevendo aqui pra mim mesmo ahahhaahah. Mas se você é um dos poucos que acompanham este blog parado tenho uma boa notícia!

Acabei de lançar a última versão do Jails, projeto de arquitetura AMD que comecei faz algum tempo já. Não imaginava que fosse chegar à esse ponto, não tinha a mínima idéia o quanto ela evoluiria desde a sua concepção lá no início. Me lembro que pensava que se eu utilizasse ela na versão 0.0.2 ( lá no comecinho ) eu iria melhorar muito meus projetos… Mal sabia o quanto ela ainda iria melhorar.

Jails 1.0.0 ( Orpheus )

Bom, todos os releases tem um codinome baseado em alguma figura mitológica, é por isso o nome estranho ali. Mas falando do que mais importa, esta versão é estável e totalmente reescrita do zero.

Quando você tem uma idéia, você a rabisca, faz rascunhos primeiro, depois lapida, testa, gera algumas versões e vê como ela se comporta em um cenário em produção.

Bom foi isso que eu fiz basicamente, quando ela se tornou promissora e realmente fazia sentido ser usada, decidi então reescrever usando os mesmos conceitos, porém melhorando a parte técnica do código. Isso faz com que melhore tanto na performance, quanto na manutenção, e abrindo novas possibilidades ao mudar algum approach.

Independente do jQuery/Zepto

Esta foi uma tarefa bem difícil pois ao contrário do que a maioria pensa, trabalhar sem jQuery é complicado. Dar suporte à maioria dos browsers não é uma tarefa fácil. O Jails ainda não dá suporte à maioria deles, mas uma característica nesta versão faz com que você acople bibliotecas nela que faz com aumente o espectro de compatibilidade. Por exemplo, se usar um Adapter jQuery 1.11 ela vai dar suporte à todos os browsers que esta versão do jQuery dá.

Repositórios – Components & Modules

No começo eu estava tão empolgado com a idéia que queria inflar o repositório com módulos e componentes. Com esta nova versão, percebi que a maioria deles tinha dependência com o jQuery/Zepto, mas não precisariam ter.

Não foi só a biblioteca que foi ganhando maturidade, mas eu também, ao utilizá-la no dia-a-dia e percebi que ao invés de ter repositórios lotados de componentes e módulos beta, eu deveria me preocupar mais com a qualidade dos componentes/módulos que eu estava escrevendo.

Eles também ganharam uma interface um pouco mais bonita, um lugar para buscar e ler sobre a documentação e ver exemplos.

Compartilhando Exemplos

No início eu hospedava em cada módulo/componente os exemplos que fazia. Isso começou a fazer menos sentido conforme fui amadurecendo o projeto, não fazia sentido criar uma série de exemplos e ficar commitando no github…( Ahh vá !! ) Oras… pra que serve jsfiddle, codepen, plunker? Então agora, os exemplos são todos hospedados nestes serviços..

Mas, existe um caso que vale a pena ser hospedado. Alguns projetos eu fazia e deixava na minha máquina, eram aplicações para testar o funcionamento e comportamento do Jails. Existem mais arquivos, e são mais complicados de serem testados em serviços de compartilhamento de código pelo fato destes serviços serem mais lentos por estarem na nuvem.

Então criei um repositório chamado Demos e lá ficam estas aplicações, no momento existem apenas duas, uma aplicação Flickr usando o serviço JSONP do próprio, e uma aplicação TodoMVC, um fork daquele projeto famoso.

Documentação…

É a parte mais chata de todas né… bom dei uma melhorada no padrão das documentações dos módulos e componentes, mas preciso ainda dar um grau na documentação do próprio Jails…

Por enquanto está lá meio capenga na wiki do projeto, mas acho que a wiki do github não tem um apelo visual dos melhores.. Acho que vou melhorar esta documentação e usar o bom e velho gitbook.

Exército de um homem só

Nem preciso dizer que não tenho qualquer suporte e/ou contribuição né? Mas isso não é de fato o que me incomoda. O que realmente me incomoda é o fato de eu não conseguir ainda “vender” este projeto, mostrar o potencial dele para as pessoas…  então é o fato de ninguém realmente ter usado que me deixa mais angustiado…

Estou sofrendo do estigma de “mais um framework javascript” e lutar para ter a atenção que React, AngularJs, Ember, Backbone é certamente uma luta perdida, praticamente Davi vs Golias.

Motivação

Mas não se trata de ganhar uma luta, ou aparecer mais que os outros… Recebi alguns comentários, emails e stars no github que me motivaram a continuar. E não são só estas as minhas motivações.

O fato é que está FUNCIONANDO, não no sentido técnico, mas no sentido filosófico, está cada vez mais fazendo sentido escrever pequenos frameworks, pequenas bibliotecas. Eu realmente estou escrevendo menos código, estou conseguindo me divertir MUITO mais desenvolvendo e estou olhando para um código antigo feito em Jails com orgulho, e não mais com aquela sensação de que tudo ficou um lixo. Inclusive pensando bem…era este meu objetivo principal.

Consigo ver agora nos projetos que utilizei o Jails, o que mais pode ser feito, ao invés de pensar em refactories. Ao invés de pensar em que módulo melhorar, pensar qual módulo poderia agregar mais ao site, como um notificador quando algum módulo do site quebra, como fazer um BI desacoplado, etc etc etc.

Agora penso muito mais em como posso agregar com outras soluções, ao invés de pensar em como posso destruir e começar tudo do zero. Mesmo que seja a única pessoa no mundo que esteja usando, já valeu MUITO à pena.

Eu já utilizei outros frameworks, outras arquiteturas, novas e antigas… já tentei de tudo. Posso dizer com um PUTA orgulho… Nenhum deles, até agora, me faz “dropar” essa iniciativa e migrar para outra solução. Simplesmente porque o projeto não mira as inovações do mercado, o projeto é pé no chão, simplicidade aqui é tudo, e a modularização faz com que qualquer coisa nova revolucionária e já consolidada, possa ser acoplada de maneira muito simples.

Posso mudar a micro-arquitetura das aplicações de acordo com o projeto, e não engessar todas elas numa única arquitetura. Mantendo sempre a simplicidade, acho que o projeto só tem a crescer mais e mais.

Abaixo cito uma das frases que mais tem feito sentido para mim nos últimos tempos, reflete a verdadeira essência do Jails, sempre penso nela quando vou refatorar o código do projeto, ou quando estou escrevendo um componente/modulo e penso que preciso colocar mais coisas:

…It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to subtract. 

Antoine de Saint Exupéry – Terre des Hommes (1939)