Desenvolva aplicações Web com Angular2 e Typescript

Recentemente publicamos um post em que abordávamos como desenvolver aplicações Javascript com Typescript. O Typescript permite desenvolver scripts com definição explícita de tipos além de programação orientada a objetos baseada em classes. Tudo isso sendo posteriormente compilado para Javascript puro em diferentes versões conforme a sua necessidade.

Nesse contexto, o Angular2 está sendo desenvolvido e já está disponível para preview. E uma das novidades dessa versão é o uso do Typescript. E hoje veremos como preparar nosso Visual Studio Code para desenvolver aplicações Web usando Angular2.

Pré-requisitos

Para seguir os passos descritos nesse post, você precisará instalar o Visual Studio Code e o Node.JS. Segue link para download das ferramentas:
Visual Studio Code
NodeJS

Preparando o Visual Studio Code

Depois de instaladas as ferramentas, vamos precisar instalar alguns módulos que usaremos durante o desenvolvimento. Para tanto, abra o prompt de comando do Node.js e execute os seguintes comandos:

npm install -g typescript

  • Lite-server: deve ser usado somente para desenvolvimento:

npm install -g lite-server

Já no Visual Studio Code vamos instalar a extensão npm necessária para usar comandos do NPM (Node Package Manager) dentro da ferramenta. Abra o Visual Studio Code, pressione F1 ou CTRL + Shift + P, escreva extensions e selecione o comando Extensions: Install Extension. Será exibida uma lista de extensões disponíveis. Escreva npm e então selecione o item npm. Será exibida uma mensagem informando que a instalação foi concluída e que o Visual Studio Code precisará ser reiniciado. Reinicie-o agora.

Criando o projeto no Visual Studio Code

No Visual Studio Code, vamos abrir uma nova pasta (File > Open Folder…). Sugiro criar aqui uma nova pasta para mantermos nosso código num local separado:

aprenda_desenvolver_aplicacoes_web_angular2_typescript_newProject

Próximo passo é incluir os arquivos necessários dentro do nosso projeto. Esses arquivos estão especificados na documentação oficial no Angular2, em https://angular.io/docs/ts/latest/quickstart.html e devem ser incluidos na raiz da pasta de nosso projeto:

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

Este arquivo provê configuração para o projeto Typescript e falamos sobre ele no noso último post. Mais detalhes podem ser obtidos no capítulo sobre configuração do Typescript.

typings.json

{
  "ambientDependencies": {
    "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd",
    "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd"
  }
}

Este arquivo provê informações e definições de tipo para serem usados no Typescript.

package.json

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "start": "concurrently \"npm run tsc:w\" \"npm run lite\" ",    
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "typings": "typings",
    "postinstall": "typings install" 
  },
  "license": "ISC",
  "dependencies": {
    "angular2": "2.0.0-beta.11",
    "systemjs": "0.19.24",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "zone.js": "0.6.4"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.1.0",
    "typescript": "^1.8.9",
    "typings":"^0.7.9"
  }
}

Aqui especificamos os pacotes NPM os quais nosso projeto depende. Através desse arquivo, o Typescript usa o NPM (disponibilizado no seu sistema pelo Node.JS) para instalar os pacotes dentro da nossa pasta, para que os mesmos possam ser referênciados. Essas dependências podem ser só de desenvolvimento, como é o caso o lite-server, instalado anteriormente nesse post.

Além disso, nesse arquivo especificamos o script para auxiliar no desenvolvimento. Podemos, por exemplo, usar o comando npm start para executar o compilador Typescript com watcher habilitado (dessa forma, os arquivos Typescript que iremos criar serão monitorados e qualquer mudança feita neles irá disparar o compilador para gerar os arquivos Javascript correspondentes) além do Lite Server.

Depois de definido o arquivo package.json, vamos executar o npm install de dentro do Visual Studio Code para instalar o pacote. Pressione F1 ou CTRL + Shift + P e então escreva e selecione o comando npm: install. Com isso temos os módulos npm instalados dentro da nossa pasta:

aprenda_desenvolver_aplicacoes_web_angular2_typescript_npminstall

Implementando a aplicação

Agora estamos prontos para criar nossa aplicação.

Vamos começar criando o arquivo Typescript com o código da nossa aplicação. Crie a pasta app e dentro dela o arquivo que será o componente principal, o app.component.ts. Nele adicione o seguinte código:

app/app.component.ts

import {Component} from 'angular2/core';
@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }

Notas:

  • Note que esse é um arquivo Typescript e posteriormente iremos compilá-lo para um Javascript.
  • Para a definição do componente, a propriedade ‘selector’ define o seletor CSS para o(s) elemento(s) do DOM (Document Object Model) referente a esse component. Já propriedade template permite definir o conteúdo desse componente. Resumindo, todo elemento obtido pelo ‘selector’ terá o conteúdo definido pelo ‘template’
  • Vamos também exportar a classe do componente. Nela iremos colocar a lógica da nossa aplicação. Mas inicialmente, vamos manter vazio.

Em seguida, vamos criar o arquivo app/main.ts:

app/main.ts

import {bootstrap}    from 'angular2/platform/browser';
import {AppComponent} from './app.component';

bootstrap(AppComponent);

Notas:

  • Estamos importando tanto o bootstrap como também o componente da nossa aplicação.
  • O Bootstrap é quem irá inicializar nossa aplicação e é específico de plataforma pois pode variar de acordo com o Target da nossa aplicação.
  • Apesar do arquivo ser pequeno, a própria documentação do Angular2 sugere manter em um arquivo a parte, já que trata da inicialização. Já o componente trata da view.

Por último vamos criar o arquivo index.html na raiz da nossa aplicação. Esse arquivo é que irá disponibilizar o conteúdo Web da nossa aplicação para o usuário.

index.html

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">    

    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>   

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Note que nessa página temos o elemento “my-app” que será posteriormente preenchido pelo “template” especificado no nosso componente. Além disso, nesse arquivo temos o script que chamará o arquivo app/main para fazer a inicialização da aplicação.

Executando a aplicação

Depois de finalizado o projeto, podemos executá-lo usando o script start npm definido por nós anteriormente no arquivo package.json.

Para executar o script, pressione F1 ou CTRL + Shift + P e então escreva e selecione o comando npm: Run script. E então selecione o script start. Esse script irá executar o compilador Typescript no modo watcher (assim como já dito anteriormente, o watcher faz com que os arquivos .ts sejam monitorados de modo que qualquer mudança feita neles dispara o compilador para gerar os arquivos Javascript correspondentes) e depois irá iniciar o lite-server, para testar a aplicação.

Compilando e executando a aplicação dentro do Visual Studio Code

Para executar a aplicação de dentro do Visual Studio Code, precisamos primeiro definir uma task para para compilar os arquivos Typescript. Pressione F1 ou CTRL + Shift + P e então escreva e selecione o comando Tasks: Configure Task Runner.

Isso irá abrir o arquivo .vscode/tasks.json ou criar um novo caso o mesmo ainda não exista. Inicialmente ele vem com várias configurações diferentes para Task Runner. Porém, vamos substituir esse arquivo pelo seguinte:

tasks.json

// Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team
// ${file}: the current opened file
// ${fileBasename}: the current opened file's basename
// ${fileDirname}: the current opened file's dirname
// ${fileExtname}: the current opened file's extension
// ${cwd}: the current working directory of the spawned process

// A task runner that calls the Typescript compiler (tsc) and
// compiles based on a tsconfig.json file that is present in
// the root of the folder open in VSCode
{
	"version": "0.1.0",

	// The command is tsc. Assumes that tsc has been installed using npm install -g typescript
	"command": "tsc",

	// The command is a shell script
	"isShellCommand": true,

	// Show the output window only if unrecognized errors occur.
	"showOutput": "silent",

	// Tell the tsc compiler to use the tsconfig.json from the open folder.
	"args": ["-p", "."],

	// use the standard tsc problem matcher to find compile problems
	// in the output.
	"problemMatcher": "$tsc"
}

Nesse arquivo estamos configurando a task para compilar os arquivos typescript a partir do arquivo de configuração tsconfig.json criado anteriormente.

Para executar essa task, pressione F1 ou CTRL + Shift + P e então escreva e selecione o comando Tasks: Run Task e então selecione a task tsc. Isso fará com que os arquivos Typescript sejam compilados para arquivos .js:

aprenda_desenvolver_aplicacoes_web_angular2_typescript_task

Notas:

  • Nesse momento podem ser indicados erros devido a definições não encontradas nos arquivos do próprio Angular2 e não da nossa aplicação. Certifique-se apenas se os arquivos .js foram gerados. Caso não tenham sido gerados, revisite os passos anteriores.
  • O tsc ficará monitorando as alterações feitas nos arquivos .ts devido as configurações que temos no arquivo tsconfig.json (propriedade "watch": true). Isso é indicado pelo Visual Studio Code na barra de status (ícone aprenda_desenvolver_aplicacoes_web_angular2_typescript_runningIcon). A qualquer sinal de mudança nos arquivos .ts, eles serão novamente compilados pelo tsc gerando assim novos arquivos Javascript.

Agora pressione “F5” para executar a aplicação. O Visual Studio Code te dará opção para selecionar qual ambiente de execução será usado. Selecione o Node.js. Depois disso, será criado o arquivo launch.json que terá a configuração para execução do projeto. Vamos substituir o conteúdo desse arquivo pelo código abaixo:

launch.json

{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "Launch",
			"type": "node",
			"request": "launch",
                        "program": "${workspaceRoot}/node_modules/lite-server/bin/lite-server",
			"stopOnEntry": false,
			"args": [],
			"cwd": "${workspaceRoot}/.",
			"runtimeExecutable": null,
			"runtimeArgs": [],
			"env": {
				"NODE_ENV": "development"
			},
			"externalConsole": false,
			"sourceMaps": false,
			"outDir": null
		},
		{
			"name": "Attach",
			"type": "node",
			"request": "attach",
			"port": 5858
		}
	]
}

Estamos especificando o programa o lite-server para executar nosso projeto. O mesmo irá carregar a pasta raiz do nosso projeto: "cwd": "${workspaceRoot}/."

aprenda_desenvolver_aplicacoes_web_angular2_typescript_run_1_vscode

Será então aberto o browser com a nossa página:

aprenda_desenvolver_aplicacoes_web_angular2_typescript_run_1_browser

Adicionando lógica na nossa aplicação

Vamos agora adicionar um pouco de lógica na nossa aplicação. Faremos uma página que faz um cálculo simples de índice de massa corporal.

Comecemos adicionando um novo arquivo HTML que será usado como template pelo componente. Vamos criar a pasta pages na raiz da pasta da nossa aplicação e então o arquivo imc-sample.html:

pages/imc-sample.html

<div class="container">
    <h2>Calculadora IMC:</h2>
    
    <div class="form-group">
        <label for="peso">Peso</label>
        <input [(ngModel)]="peso" id="peso" type="number" step="0.1" class="form-control" />
    </div>
    
    <div class="form-group">
        <label for="altura">Altura</label>
        <input [(ngModel)]="altura" id="altura" type="number" step="0.1" class="form-control" />
    </div>
    
    <button (click)="calcularIMC()" class="btn btn-default">Calcular IMC</button>
    
    <p>    
        {{resultadoIMC}}
    </p>
</div>    

O uso do “[()]” indica bind (ligação) de duas vias com o Model representado pelo ngModel. Já o “()” é um bind de uma via (do Model para View). Por fim, o {{ }} permite obter uma valor do Model e exibí-lo na página.

Agora vamos alterar o arquivo do componente para usar esse arquivo e também para adicionar a lógica da aplicação:

app/app.component.ts

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    templateUrl: 'pages/imc-sample.html'
})

export class AppComponent { 
    
    peso = 0;
    altura = 0;
    imc = 0;
    resultadoIMC = '';
    
    calcularIMC(){
        if (this.altura <= 0 || this.peso <= 0)
        {
            this.resultadoIMC ='Valor de peso e altura deve ser maior que zero.';    
        }
        else
        {        
            var imc = this.peso / Math.pow(this.altura, 2);
            var resultado;
            
            if (imc < 17)
            {                
                resultado ='muito abaixo do peso';       
            }
            else if (imc < 18.49)
            {
                resultado ='abaixo do peso';
            }
            else if (imc < 24.99)
            {
                resultado ='com peso normal';
            }
            else if (imc < 29.99)
            {
                resultado ='acima do peso';
            }
            else if (imc < 34.99)
            {
                resultado ='com obesidade grau 1';
            }
            else if (imc < 39.99)
            {
                resultado ='com obesidade grau 2 (severa)';
            }
            else
            {
                resultado ='com obesidade grau 3 (morbida)';
            }
            
            this.resultadoIMC =`Seu IMC é ${imc}. Você está ${resultado}!`;
        }
    }    
}

Note na linha destacada que agora estamos especificando a URL com o template do componente.

Vamos ainda incluir o Twitter Bootstrap na nossa página principal:

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">    
    
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"/>

    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>   

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>    
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
        
    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Agora vamos executar a task tsc. Pressione F1 ou CTRL + Shift + P e então escreva e selecione o comando Tasks: Run Task e então selecione tsc.

Depois disso, pressione “F5” novamente para executar a aplicação.

E é isso pessoal! Os arquivos fonte do exemplo acima podem ser baixados do repositório GitHub do Talkitbr. E não deixem de adicionar comentários com suas dúvidas, sugestões e dicas. Ainda iremos continuar publicando mais posts sobre Angular2 e Typescript e a sua colaboração é fundamental. Abraços e até a próxima!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s