Tempo de leitura: 9 minutos
Motivação
Existem diversos frameworks de JavaScript atualmente. Então porque você deveria trabalhar com AngularJS ao invés dos outros?
Modularização
A modularização facilita o desenvolvimento, a configuração e principalmente, os testes da sua aplicação. O AngularJS vem com um mecanismo de Injeção de Dependências built-in, por exemplo, que transforma a tarefa de dividir a sua aplicação em pequenos módulos em algo trivial.
Two-way Data Binding
Uma das features mais polêmicas do AngularJS é o Two-way Data Binding. Apesar de ser muito útil e um dos grandes fatores para o sucesso do framework no começo, ela pode apresentar problemas de perfomance caso não seja usada corretamente.
Extensibilidade
Estender o HTML com o AngularJS, usando diretivas, é a feature mais incrível do framework. Diretivas são poderosas ferramentas para modificar e manipular o DOM, além de ter a facilidade de reuso em toda a aplicação.
Ferramentas
Sublime Text
O editor mais usado para desenvolver aplicações com AngularJS continua sendo o Sublime Text. Além de ser bem leve e fácil de usar, ele possui um package (plugin) específico para o AngularJS.
Jasmine
O Jasmine foi desenvolvido para ser usado em BDD (behavior-driven development), porém ele geralmente é usado em AngularJS para testes unitários e TDD (test-driven development).
Karma
Karma é um test runner feito para o AngularJS (apesar de atualmente você poder usá-lo com outros frameworks JavaScript). O principal objetivo do Karma é automatizar os testes em diversos browsers com um simples comando. Uma das vantagens é que ele suporta diversos tipos de testes, como: unitários, integração e E2E.
Bower
O Bower, criado como um projeto Open-Source do Twitter, foi desenvolvido para facilitar o uso de bibliotecas e pacotes em um projeto web. É possível inclusive, desenvolver pacotes próprios e distribuí-los em diferentes projetos de forma fácil.
Grunt
Em diversas ocasiões, nós desenvolvedores, enfrentamos tarefas repetitivas que podem ser facilmente automatizadas. É aí que entra o Grunt. Ele é usado para: minificação, linting de JavaScript e geração de builds.
Exemplo de Aplicação
Setup
Para começarmos a nosso setup, precisamos instalar o Bower. Assumindo que você já tem o NPM instalado, precisamos apenas de:
$ npm install -g bower
Agora, crie uma pasta chamada app-exemplo, entre nela e crie um arquivo de configuração do Bower:
$ mkdir app-exemplo $ cd app-exemplo $ bower init
Aceite todos os defaults e o seu bower.json deverá estar próximo disso:
/// bower.json
{
"name": "app-exemplo",
"version": "0.0.0",
"authors": [
"Matheus Lima <matheusml90@gmail.com>"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
Agora, para instalar o AngularJS, devemos adicionar a dependência no Bower. E para isso basta digitar:
$ bower install --save angular
Observe que foi criada uma pasta chamada bower_components. Nessa pasta estarão todas as dependências do Bower.
Além disso, o arquivo bower.json foi automaticamente modificado. Ficando dessa forma:
/// bower.json
{
"name": "app-exemplo",
"version": "0.0.0",
"authors": [
"Matheus Lima <matheusml90@gmail.com>"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"angular": "~1.4.3"
}
}
É altamente recomendável adicionar a pasta bower_components no .gitignore. Para fazermos isso, basta primeiramente criar o arquivo:
$ touch .gitignore
E dentro do .gitignore, precisamos deixá-lo dessa forma:
/// .gitignore
bower_components
Agora, falta criar o index.html da nossa aplicação:
$ mkdir app $ cd app $ touch index.html
E nele, importar o arquivo minificado do AngularJS, que veio do Bower, para que a aplicação possa funcionar.
/// index.html
<html>
<head>
<title>AngularJS</title>
</head>
<body>
<h1>AngularJS</h1>
<script type="application/javascript" src="../bower_components/angular/angular.min.js"></script>
</body>
</html>
Precisamos também de um servidor para rodar nossa aplicação e ver que nosso index.html funciona. Vamos usar o http-server que pode ser baixado pelo NPM:
$ npm install -g http-server $ cd .. $ http-server
Agora, basta entrar em http://localhost:8080/ e devemos visualizar algo próximo disso:
Para padronizar e facilitar o start e os testes da aplicação, precisamos configurar um package.json (que é utilizado pelo NPM):
$ npm init
Aceite todos os defaults e ele deverá ficar semelhante a isso:
///package.json
{
“name”: “app-exemplo”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1"
},
“author”: “”,
“license”: “ISC”
}
Para que possamos iniciar a aplicação com apenas um comando, vamos editar o arquivo adicionando apenas uma linha:
///package.json
{
“name”: “app-exemplo”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {
"start": "http-server ./app -a localhost -p 8080",
“test”: “echo \”Error: no test specified\” && exit 1"
},
“author”: “”,
“license”: “ISC”
}
Com essa modificação, podemos rodar a aplicação da seguinte forma:
$ npm start
E acessando http://localhost:8080/ você deverá ver isso:
index.html
Arquitetura
Agora que fizemos o setup básico, podemos partir para o modelo de arquitetura de aplicações em AngularJS que usamos aqui na Concrete Solutions.
- Estrutura Todos nossos Controllers, Services, Factories e Diretivas seguem a mesma estrutura:
(function() {
'use strict';
angular
.module('app')
.controller('AuthController', AuthController);
function AuthController() {
/* código */
}
})();
Se você não entendeu a primeira e a última linhas, esse padrão bem comum em projetos com JavaScript, é chamado de IIFE. Recomendo esse post para você entender todos os detalhes dele.
Outro padrão bem comum que nós usamos é o ‘use strict’, que serve resumidamente para melhorar o processo de verificação de erros no código.
E por último, vale notar que nós usamos uma abordagem Top-Down, em que as declarações ficam na parte de cima do arquivo, e a implementação fica em baixo.
2. Injeção de Dependências
Nós usamos o método $inject para fazer DI:
(function() {
'use strict';
angular
.module('app')
.controller('AuthController', AuthController);
AuthController.$inject = ['$location', 'AuthService'];
function AuthController($location, AuthService) {
/* código */
}
})();
A grande vantagem é a facilidade na minificação de arquivos (visto que as dependências são trazidas como Strings).
3. Controllers
function AuthController($location, AuthService) {
var vm = this;
vm.login = login;
function login(email, password) {
AuthService.login(email, password).then(function() {
$location.path('/');
});
}
}
Tentamos manter os Controllers o mais lean possível, com pouca lógica, e seguindo o Single Responsability Principle. Dessa forma eles ficam mais fáceis de manter, ler e testar.
Usamos também o padrão do ControllerAs com a variável vm, proposta pelo John Papa. Uma das vantagens é a não necessidade de se importar o $scopenos Controllers.
4. Comunicação com o Back-End
Preferimos encapsular chamadas $http em Services:
function AuthService($http) {
this.login = function(email, password) {
var request = {
username: email,
password: password
};
return $http.post(url, request);
};
}
Um dos focos dessa abordagem é o Separation of Concerns. Ou seja, não é responsabilidade dos Controllers lidar com a lógica da comunicação com o Back-End e sim de um serviço feito apenas para lidar com isso.
5. Factory
Uma das formas de se compartilhar dados numa aplicação com AngularJS é feita com o uso das Factories. Como elas são singletons, os dados não se perdem na mudança de contexto. Um bom caso de uso é a criação de uma Session:
function Session($cookieStore) {
return {
create: create,
destroy: destroy,
isAuthenticated: isAuthenticated
};
function create(id) {
$cookieStore.put('session', id);
}
function destroy() {
$cookieStore.remove('session');
}
function isAuthenticated() {
!!$cookieStore.get('session');
}
}
Nesse exemplo mostrado, podemos acessar de qualquer Controller a sessão do usuário e verificar se ele está autenticado ou não.
Uma dúvida recorrente é a diferença entre Factories e Services que eu expliquei anteriormente nesse post aqui.
6. Diretivas
Assim como Controllers, as Diretivas devem ser desenvolvidas com o Single Responsability Principle em mente. Se uma Diretiva resolve múltiplos problemas ao mesmo tempo, ela dificilmente será reaproveitada e perderá todo sentido de existir (que é justamente o reuso).
O exemplo abaixo mostra uma Diretiva que dá foco a um input:
function NgFocus($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
$timeout(function() {
element[0].focus();
}, 0);
}
};
}
Nota-se que a Diretiva em questão tem apenas um objetivo. Se ela além de dar foco ao input, tivesse que adicionar a cor verde no background do mesmo, ela certamente perderia o reuso na maioria dos casos.
Um bom post sobre Diretivas é esse aqui do Todd Motto.
Continuous Delivery
É comum investirmos alguns sprints no início dos projetos para arquitetar a infraestrutura que dará suporte aos desenvolvedores da primeira linha de código até a última. Isso significa montar e estruturar a integração contínua, o deployment contínuo e automatizar os processos de desenvolvimento e suporte. As principais vantagens do Continuous Delivery são:
- Aumento da transparência
- Aumento do feedback
- Releases frequentes
- Maior confiança em cada entrega.
- Desenvolvedores podem focar mais na qualidade do código e menos em builds e deploys.
Para automatizar nosso processo de CI, escolhemos o Jenkins como ferramenta. Primeiro deve-se decidir o que o Jenkins deve fazer no processo de deployment, que podem ser resumidos em 6 comandos:
$ npm install grunt -g $ npm install bower -g $ npm install $ bower install $ npm test $ grunt dev
- Instalar o Grunt
- Instalar o Bower
- Instalar todos os packages do NPM
- Instalar todos os packages do Bower
- Rodar os testes usando o Karma
- Gerar o Build usando o Grunt
Após esse procedimento, o Jenkins gera um relatório de cobertura de testes (que pode ser configurado pelo Karma dessa forma):
Cobertura de testes gerado pelo Jenkins
Esse relatório tem grande utilidade para os Tech Leads para verificar a qualidade do código durante todo o andamento do projeto.
Conclusão
Para quem ainda possuir mais dúvidas de como trabalhar com AngularJS, uma boa dica é a minha série sobre AngularJS no YouTube, que vai dos primeiros passos até a construção de diretivas avançadas:
The post Como trabalhar com AngularJS — O Guia Absolutamente Completo appeared first on Eu Sou Dev.







index.html
Cobertura de testes gerado pelo Jenkins
Top comments (0)