Seja no deploy de uma aplicação desktop com instalação local, uma aplicação web ou um aplicativo mobile, precisamos nos certificar de algumas coisas. Primeiro, é necessário que os ambientes de desenvolvimento e de produção estejam totalmente compatíveis, tendo as mesmas configurações e versões de linguagem, bibliotecas e Sistema Operacional, dentre outras dependências do projeto. Por último, devemos nos certificar de que todas as configurações da aplicação estão adequadas para produção: se a aplicação consome um banco de dados, precisamos apontá-la para o banco de dados de produção, se consome uma API, devemos apontá-la para a API de produção também, etc.
O próprio deploy também pode ser um ponto de falha, pelos motivos citados anteriormente, e, por isso, devemos nos cercar de todos os tipos de testes, bem como automatizar o máximo possível desse processo. Alguns serviços de Cloud fornecem soluções prontas-para-uso que permitem a automatização do deploy com pouca ou nenhuma configuração. Um desses serviços é o Heroku, uma das plataformas de execução de aplicações em Cloud mais simples e comuns do mercado.
Nesse artigo veremos como realizar o deploy no Heroku de uma aplicação construída com o Angular. Utilizaremos as ferramentas de build do próprio Angular CLI para gerar os arquivos finais da nossa aplicação, bem como o Heroku CLI para a criação e envio da aplicação para o Heroku. Ao final do processo seremos capazes de realizar alterações na aplicação em produção apenas dando o PUSH das modificações para um repositório GIT disponibilizado pelo Heroku. Não se preocupe, utilizaremos o plano gratuito.
Faremos o deploy da aplicação desenvolvida no projeto App Fullstack com cadastro/login em Node e Angular. Se preferir, pode criar uma aplicação do zero utilizando o Angular CLI, basta acompanhar o passo a passo que demos no curso Angular: Conectando com uma API RESTful.
Servidor web com Node.js + Express
Uma aplicação Angular, após o build, consiste de um arquivo index.html e alguns arquivos .js e .css, nada mais. Se dermos um duplo clique nesse arquivo .html, veremos nossa aplicação funcionando perfeitamente no navegador.
Entretanto, para que possamos disponibilizá-la como uma aplicação web, precisaremos de um servidor que seja capaz de receber requisições HTTP e enviar os arquivos da aplicação, uma vez que forem requisitados. Como estamos falando de uma página estática (os arquivos não são gerados a cada requisição, apenas servidos ao navegador do usuário), poderíamos utilizar até o mesmo o GitHub Pages.
Poderíamos optar por um servidor HTTP como o Apache e Nginx, mas também pode ser uma pequena aplicação Node.js. Neste artigo seguiremos essa abordagem e criaremos um pequeno servidor HTTP utilizando o Node.js e o framework Express. Esse servidor HTTP terá uma única função: ao receber uma requisição deve fornecer os arquivos estáticos da aplicação.
Utilizaremos o NPM para instalar o Express. Para isso, abra o terminal e, no diretório do projeto, execute o seguinte comando:
npm install express --save
Obs: O parâmetro --save salvará o nome e versão do Express no arquivo package.json. Isso será necessário para que, mais adiante, o Heroku saiba quais dependências deve instalar para que a aplicação funcione corretamente.
No diretório raiz da nossa aplicação, no mesmo nível que o arquivo package.json, criaremos o nosso servidor em um arquivo chamado server.js:
const express = require('express');
const path = require('path');
const nomeApp = process.env.npm_package_name;
const app = express();
app.use(express.static(`${__dirname}/dist/${nomeApp}`));
app.get('/*', (req, res) => {
res.sendFile(path.join(`${__dirname}/dist/${nomeApp}/index.html`));
});
app.listen(process.env.PORT || 8080);
-
Linhas 1 e 2: Importamos o Express instalado anteriormente e o modulo Path do Node.js.
const express = require('express'); const path = require('path');
-
Linhas 3 e 4: Ao iniciar uma aplicação utilizando o NPM, teremos disponíveis variáveis de ambiente que nos permitem acessar dados do arquivo package.json. Utilizaremos esse recurso para obter o nome do pacote, pois, ao construir a aplicação, o Angular CLI irá disponibilizar os arquivos desta no diretório /dist/nome-do-pacote. Criamos, também, uma instância do Express.
const nomeApp = process.env.npm_package_name; const app = express();
-
Linhas 7 e 10: Disponibilizamos todos os arquivos estáticos gerados ao construir a aplicação, bem como uma rota que responderá com o arquivo index.html para qualquer requisição GET.
app.use(express.static(`${__dirname}/dist/${nomeApp}`)); app.get('/*', (req, res) => { res.sendFile(path.join(`${__dirname}/dist/${nomeApp}/index.html`)); });
-
Linha 12: Iniciamos o servidor escutando na porta da variável de ambiente PORT disponibilizada pelo Heroku ou, caso esta não esteja definida, na porta 8080 para que possamos executá-la localmente.
app.listen(process.env.PORT || 8080);
Modificando o package.json
Agora que temos nosso servidor pronto, precisamos modificar o package.json para adicionar algumas informações importantes para o Heroku, tais como a forma que a aplicação deve ser construída e iniciada.
Uma vez que o Heroku inicia a aplicação através do comando npm start devemos, no atributo scripts do nosso package.json, especificar a forma que a aplicação deve ser executada. Além disso, criaremos um novo script chamado postinstall, que será executado assim que todas as dependências forem instaladas. Esse script é necessário para que possamos construir o pacote final da nossa aplicação e disponibilizá-la no diretório /dist/nome-do-pacote.
Por fim, no mesmo arquivo, criaremos um atributo chamado engines que receberá as versões do Node.js e do NPM que devem ser utilizadas pelo Heroku. É recomendado utilizar em produção as mesmas versões que foram utilizadas no desenvolvimento e podemos obtê-las através dos comandos npm -v e node -v.
{
"name": "nome-do-pacote",
...
"scripts": {
...
"start": "node server.js",
"postinstall": "ng build --aot --prod"
},
...
"engines": {
"node": "10.13.0",
"npm": "6.4.1"
}
}
Executando a aplicação Angular no Heroku
Nessa etapa do artigo criaremos uma instância no Heroku e enviaremos os arquivos da nossa aplicação para o repositório disponibilizado pelo mesmo. Lembre-se: você deve possuir uma conta no Heroku, o Heroku CLI e o GIT instalados na sua máquina.
No diretório raiz da aplicação, a partir do Heroku CLI, utilizaremos o seguinte comando para criar a instância onde será executada nosso pequeno servidor Node.js:
heroku create
Ao final da execução, o Heroku terá criado um endereço aleatório para a nossa aplicação e um repositório GIT para onde enviaremos os arquivos da mesma.
Creating app... done, ⬢ fast-citadel-90247
https://fast-citadel-90247.herokuapp.com/ | https://git.heroku.com/fast-citadel-90247.git
Feito isso, podemos commitar todos os arquivos da nossa aplicação e realizar o push para o branch Master do repositório criado anteriormente. Esse repositório pode ser utilizado da mesma forma que qualquer outro repositório Git remoto, como o GitHub e Bitbucket, por exemplo, mas o Heroku só reconstruirá a aplicação caso o commit seja realizado no branch Master:
git add .
git commit -m ":rocket: Meu primeiro deploy no Heroku!"
git push heroku master
Dado que o Heroku ficará responsável por instalar todas as dependências, construir a aplicação e executar o servidor, pode ser que a execução do comando acima dure alguns minutos. Quando o mesmo terminar, seremos capazes de acessar nossa aplicação através do endereço informado pelo Heroku, assim como pode ser visto na barra de navegação na Figura 1.

Gostou do assunto e está interessado a aprender mais sobre Angular? Deixe um joinha! Tem uma opinião sobre o Heroku ou outros servidores Cloud? Deixe nos comentários, estamos loucos para saber sobre a experiência de vocês ;)