Back-end com Typescript para iniciantes
Considerações do escritor
Tenho duas coisas a dizer, primeiramente gostaria de expressar minha felicidade e orgulho em ter um ambiente como o tabnews na internet, o potencial desse sistema ainda não tá escrito rsrsrs. O segundo ponto, é o fato desse artigo ser uma aventura para mim, não sou um bom escritor (como irão perceber ao longo da leitura), então peço a colaboração de vocês para tornar esse artigo um bom material. Irei manter em constante manutenção, feedbacks construtivos serão muuuuuito bem-vindos.
Introdução
Olá, eu me chamo Tiago de Castro e pretendo com esse artigo, de forma simples e didática, mostrar o processo que uso para desenvolver aplicações back-end usando typescript junto ao express. A primeiro momento, será abrangido um escopo bem limitado, tratando somente o inicio do projeto até o “app.boot()
”, pois minha intenção é explicar da melhor forma possível o básico.
Para este artigo, abordarei:
- Iniciando o projeto;
- Instalando as dependências;
- Adicionando suporte ao Typescript;
- Configurações básicas no tsconfig;
- Script package.json;
- Desenvolvendo boot do servidor.
- Configuração do Express
- Server
- Setup
- Boot
Iniciando o projeto
Pré-requisitos
É necessário que você tenha em sua máquina o node instalado.
Link para o node: https://nodejs.org/en/
💡A instalação do Node é acompanhada por um gerenciador de pacotes chamado NPM (Node Package Manager).
Criando nosso package.json
Dentro da pasta onde deseja armazenar o projeto, utilize o npm init para inicializar um projeto node:
> npm init
# caso queira passar por todos os processos de uma vez, utilize a flag -y
Com esse comando será criado em nosso projeto o package.json
, que é um arquivo de configuração utilizado para estipular e configurar dependências do seu projeto (quais outros pacotes ele vai precisar para ser executado) e scripts automatizados. Através dele conseguimos deixar claro uma "receita" para executar um projeto.
Antes de colocar a mão na massa, um importante conceito!
De grosso modo, o funcionamento do node é baseado na interpretação de comandos desenvolvidos em javascript. Então, como desenvolver para essa mesma ferramenta utilizando o typescript?
Um transpilador de código é basicamente converter um código para outro. Por exemplo, TypeScript é uma linguagem de alto nível, mas depois que é transpilada, é transformada em JavaScript (outra linguagem de alto nível).
É um importante conceito, pois trabalhar com typescript no node é basicamente isso, você desenvolve o projeto em uma linguagem que não consegue ser interpretada pelo node, tornando-se necessário o uso de transpiladores.
Instalando as dependências
Um dos principais momentos no desenvolvimento de um projeto é a adição de pacotes externos, sendo de extrema importância o entendimento do escopo onde esses pacotes são inseridos, por exemplo, algumas funcionalidade só fazem sentindo na minha máquina, na qual o projeto está em desenvolvimento (seria o caso do typescript).
Dito isso, teremos dois tipos de dependências, as de desenvolvimento e as de produção.
Dependências de desenvolvimento
@types/<pacote>
→ essa anotação significa a instalação dos tipos de um determinado pacote
@types/node
→ este pacote contém definições de tipo para o Node.js;@types/express
→ este pacote contém definições de tipo para o express;ts-node
→ transforma o TypeScript em JavaScript, permitindo que você execute diretamente o TypeScript no Node.js sem pré-compilar;typescript
→ A linguagem propriamente dita.
> npm i --save-dev @types/node @types/express ts-node typescript
# caso queira, subistitua a flag --save-dev por -D
Dependências de produção
express
→ nosso “framework”rimraf
→ tem a função de remover algo quando executado (fará sentindo no futuro)dotenv
→ nos permite acessar nosso.env
> npm i express rimraf dotenv
# caso queira, subistitua a flag --save-dev por -D
Gerando o meu tsconfig.json
Em seguida, precisamos iniciar e configurar o projeto typescript. Para isso, utilizaremos o comando npx tsc --init
.
💡 caso ela fosse instalada globalmente (em minha máquina), eu poderia acessar o comando
simplesmente com tsc --init
> npx tsc --init
Ao rodar esse comando, é gerado um arquivo tsconfig.json
, o qual tem a função de especificar os arquivos raiz e as configurações de compilação necessárias para o projeto.
Configurando
Iremos realizar uma configuração simples e rápida, alterando somente dois atributos:
"rootDir": "./src”
- Essa configuração define a pasta onde ficará o index (O boot) da aplicação. Irei utilizar como pasta raiz a
./src
- Essa configuração define a pasta onde ficará o index (O boot) da aplicação. Irei utilizar como pasta raiz a
"outDir": "./dist"
- Essa configuração define o local onde ficará o meu código transpilado para javascript, é este o lugar onde o meu servidor usará para rodar em produção
Configurando meu package.json
Vamos realizar 3 configurações básicas no package.json
relacionadas a scripts de execução, serão eles o nosso start do projeto como desenvolvedor, o build e o start do projeto em produção.
"scripts": {
"dev": "ts-node ./src/index.ts",
"build": "rimraf ./dist && tsc",
"start": "node ./dist/index"
}
- Dev
- Esse comando será o responsável por dar o start do projeto em nosso ambiente de desenvolvimento, ele consegue transpilar o typescript em javascript sem a necessidade de compilar o código.
- Build
- O build é a transpilação do código, para isso, primeiro é utilizado o rimraf que realiza a remoção da pasta dist (com a antiga transpilação do código) e executa o comando tsc, quem irá criar uma pasta com o código traspilado (essa pasta criada foi definida na propriedade
outDir
dentro das configurações do meutsconfig
).
- O build é a transpilação do código, para isso, primeiro é utilizado o rimraf que realiza a remoção da pasta dist (com a antiga transpilação do código) e executa o comando tsc, quem irá criar uma pasta com o código traspilado (essa pasta criada foi definida na propriedade
- Start
- Nada mais é que a execução pelo node do código transpilado.
Mão na massa
Após essa rápida configuração, que a primeiro momento pode ser maçante, mas ao decorrer do tempo se torna um processo natural, vamos seguir a estruturação de pastar e a configuração de boot do nosso sistema.
Definindo estrutura do projeto
A nossa árvore de pastas ficará mais ou menos assim:
Antes de tudo, vamos preparar uma configuração do Express, ela será definida a parte para facilitar uma possível alteração no futuro, para que fique dinâmico o processo. Primeiro criaremos um arquivo .env
na raiz do nosso projeto, é nele que ficará nossas configurações de ambiente.
💡 Um segundo .env.example
é recomendado caso suba o projeto para o github, pois o .env
original pode conter informações sensíveis, sendo comumente adicionado ao .gitignore
.
PORT=3000
Em seguida, iremos definir um objeto com as configurações do express, a única por enquanto, definirá a porta do servidor. Será inserida no arquivo src/Config/Express.ts
:
💡 Caso tenha dificuldade na criação das pastas, siga a foto da árvore de pastas
export const expressConfig = {
port: process.env.PORT
}
Já configurado o express, vamos começar pela configuração do nosso servidor src/Setup/Server/index.ts
:
💡 Crie as pastas a medida em que realiza a implementação, para entender melhor o fluxo dos processos.
//1
import express, { Express } from "express"
//2
import { expressConfig } from "../../Config/Express"
class Server {
//3
private app: Express = express()
//5
start() {
this.initServer()
}
//4
private initServer() {
this.app.listen(expressConfig.port, () => {
console.log(`Server is running... [PORT ${expressConfig.port}]`)
})
}
}
export default Server
- Começamos pela importação do nosso express, bem como a sua tipagem.
- Também importamos uma configuração externa, que ainda será definida, mas basicamente é a porta em que o nosso servidor irá rodar
- Decidi separa essa configuração de forma que seja possível qualquer outro arquivo resgatar esse valor, bem como eu tenha só um lugar de mudança caso eu troque de porta.
- Defino uma propriedade privada (seguindo sempre que possível o conceito de encapsulamento) que será o meu próprio express.
- Método privado que terá como função somente iniciar o meu servidor, observe que o primeiro parâmetro do
listen()
é a porta, sendo esse valor o definido em um arquivo externo- Já realizamos a configuração do mesmo.
Em seguida iremos configurar o setup src/Setup/index.ts
:
import Server from "./Server";
class Setup {
//1
private server: Server
//2
constructor () {
this.server = new Server()
}
//3
boot () {
this.server.start()
}
}
export default Setup
- Criamos um parâmetro chamado
server
, e definimos seu tipo com a classeServer
- Nossa classe
Setup
terá um construtor, que quando instanciado, irá instanciar minha classe desenvolvida no último passo - Método
boot()
é o responsável por dar o ponta pé inicial nos processos, no caso desse exemplo, ele irá dar o start em meu servidor.
Por fim e não menos importante, iremos definir o nosso arquivo de boot que ficara na raiz do projeto src/index.ts
import "dotenv/config"
import Setup from "./Setup"
//2
const app = new Setup()
//1
app.boot()
export default app
Por fim, e não menos importante, esse é a maneira que iremos iniciar nossa aplicação.
Rodando a aplicação
Abra o terminal no vscode, e no prompt digite npm run dev
, caso tudo tenha ocorrido bem, aparecerá esse log:
Teste também a transpilação com npm run build
, para saber se ocorreu certo, fique atento a pasta dist, caso ela exista em seu projeto, o build deu bom. Por fim e não menos importante, teste a aplicação em produção com npm run start
, caso apareça o mesmo log da imagem a cima, também deu bom!
Conclusão
A ideia desse artigo é apresentar uma configuração básica de projeto utilizando o typescript, bem como a explicação da teoria. Espero que ao final do artigo, o leitor seja capaz de aplicar os conceitos ensinados, e não só copiar o código.
Futuras atualizações serão feitas, a primeira será a construção de rotas dinâmicas.
Referências
https://dev.to/rogeriorioli/iniciando-um-projeto-nodejs-express-com-typescript-4bfl
https://rockcontent.com/br/blog/npm/
https://nodejs.reativa.dev/0027-npm-dependencies-devdependencies/index
https://www.luiztools.com.br/post/como-usar-typescript-com-node-js-2/#:~:text=Todos os pacotes %40types são,js%2C como nosso comando require
https://www.typescriptlang.org/pt/docs/handbook/tsconfig-json.html#:~:text=O arquivo tsconfig.,já estão habilitadas por padrão
https://gabrieluizramos.com.br/entendendo-o-package-json