Experts in Angular

ConfiguraçõesO que é um tsconfig.json?
Você, programador Angular curioso, já reparou que em todo projeto TypeScript há um tal arquivo chamado tsconfig.json? Talvez você tenha se perguntado o que ele faz e por que ele é tão importante. Vamos mergulhar nessa história, explorar a razão da sua existência e entender como ele desempenha um papel crucial na evolução do Angular e do TypeScript.

O que é um tsconfig.json?

Você, programador Angular curioso, já reparou que em todo projeto TypeScript há um tal arquivo chamado tsconfig.json? Talvez você tenha se perguntado o que ele faz e por que ele é tão importante. Vamos mergulhar nessa história, explorar a razão da sua existência e entender como ele desempenha um papel crucial na evolução do Angular e do TypeScript.

A História do TypeScript e do Angular

No início, JavaScript reinava soberano no mundo do desenvolvimento web. Mas, com o crescimento da complexidade das aplicações, tornou-se claro que JavaScript precisava de algumas melhorias para lidar com os desafios modernos. Foi então que a Microsoft apresentou o TypeScript, uma linguagem que adiciona tipagem estática ao JavaScript, permitindo aos desenvolvedores escreverem código mais robusto e escalável.

Enquanto isso, a equipe do Angular, liderada pelo Google, estava trabalhando arduamente para transformar seu popular framework AngularJS em algo mais moderno e eficiente. Assim nasceu o Angular, uma reescrita completa que adotou TypeScript como sua linguagem principal. A combinação de Angular e TypeScript foi um casamento perfeito: Angular trouxe a estrutura e a modularidade, enquanto TypeScript adicionou segurança e clareza ao código.

Dependency Injection (DI) no Angular

Um dos pilares que fez o Angular se destacar foi seu sofisticado sistema de injeção de dependências (DI – Dependency Injection). O DI facilita a gestão de dependências e promove um código mais limpo e modular. Quando o Angular adotou TypeScript, ele trouxe consigo esse poderoso mecanismo de DI, que se integrou perfeitamente ao ambiente fortemente tipado do TypeScript.

No Angular, o DI permite que os desenvolvedores definam dependências de uma maneira declarativa, gerenciando automaticamente a criação e injeção de objetos. Isso não apenas simplifica o código, mas também melhora a testabilidade e a manutenção da aplicação.

O Papel do tsconfig.json

O tsconfig.json é o ponto de partida para qualquer projeto TypeScript. Ele informa ao compilador quais arquivos devem ser compilados e quais configurações usar. Pense nele como um maestro que dirige uma orquestra, garantindo que cada músico (arquivo TypeScript) toque sua parte corretamente, resultando em uma sinfonia harmoniosa.

Relação entre tsconfig.json e tsconfig.app.json

Enquanto o tsconfig.json é o ponto de partida geral para qualquer projeto TypeScript, definindo as opções de compilação e os arquivos a serem incluídos, o tsconfig.app.json é mais específico para a configuração do aplicativo Angular. Este arquivo estende o tsconfig.json, herda suas configurações e pode adicionar ou sobrescrever opções específicas para a compilação da aplicação.

Exemplo de tsconfig.app.json

Aqui está um exemplo típico de um arquivo tsconfig.app.json em um projeto Angular:

/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [
      "node"
    ]
  },
  "files": [
    "src/main.ts",
    "src/main.server.ts",
    "server.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

Detalhes do tsconfig.app.json

  • extends: Esta propriedade indica que o tsconfig.app.json herda as configurações do arquivo tsconfig.json localizado no mesmo diretório. Isso permite uma configuração centralizada e consistente, enquanto possibilita ajustes específicos para a aplicação.
  • compilerOptions: Esta seção pode sobrescrever ou adicionar opções específicas para a compilação do código da aplicação. No exemplo acima, outDir define o diretório de saída para os arquivos compilados da aplicação.
  • files: Especifica arquivos individuais a serem incluídos na compilação. No contexto de uma aplicação Angular, geralmente inclui o arquivo principal main.ts.
  • include: Define padrões globais para incluir arquivos na compilação. No exemplo, todos os arquivos de definição de tipos (.d.ts) na pasta src são incluídos.
  • exclude: Lista arquivos e diretórios a serem excluídos da compilação. Isso pode incluir arquivos de teste e outros arquivos específicos que não devem ser compilados no aplicativo final.
  • angularCompilerOptions: Inclui opções específicas do compilador Angular, como strictTemplates, preserveWhitespaces, sourceMap e declaration, ajustando ainda mais o comportamento da compilação Angular.

Compilando um Projeto TypeScript

Um projeto TypeScript pode ser compilado de várias maneiras, cada uma adequada a diferentes necessidades:

  1. Usando tsconfig.json ou jsconfig.json:
    • A presença desses arquivos define os parâmetros de compilação e os arquivos incluídos no processo. Eles são como o roteiro de um filme, garantindo que todas as cenas necessárias sejam filmadas.
  2. Invocando tsc sem arquivos de entrada:
    • O compilador busca pelo arquivo tsconfig.json começando no diretório atual e continuando pela cadeia de diretórios pai, como um detetive seguindo pistas.
  3. Invocando tsc com a opção de linha de comando --project (ou apenas -p):
    • Esta opção especifica o caminho de um diretório contendo um arquivo tsconfig.json, ou um caminho para um arquivo .json válido contendo as configurações, semelhante a um GPS que guia o caminho até o destino.

Quando arquivos de entrada são especificados na linha de comando, os arquivos tsconfig.json são ignorados, como se um diretor escolhesse filmar apenas cenas específicas, ignorando o roteiro completo.

Exemplos

Exemplo com a Propriedade files

O uso da propriedade files permite especificar diretamente quais arquivos TypeScript devem ser compilados, garantindo que apenas os arquivos listados sejam incluídos no projeto final.

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true
  },
  "files": [
    "core.ts",
    "sys.ts",
    "types.ts",
    "scanner.ts",
    "parser.ts",
    "utilities.ts",
    "binder.ts",
    "checker.ts",
    "emitter.ts",
    "program.ts",
    "commandLineParser.ts",
    "tsc.ts",
    "diagnosticInformationMap.generated.ts"
  ]
}
Exemplo com as Propriedades include e exclude

O uso das propriedades include e exclude permite definir padrões globais de inclusão e exclusão de arquivos, como um editor que decide incluir todos os capítulos de uma série específica, exceto aqueles marcados como rascunhos ou testes.

{
  "compilerOptions": {
    "module": "system",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "outFile": "../../built/local/tsc.js",
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["**/*.spec.ts"]
}

Entendendo o tsconfig.json

A chave para entender o tsconfig.json está em compreender suas propriedades principais e como elas influenciam a compilação do projeto, assim como um maestro entende as nuances da partitura que conduz.

compilerOptions

Esta seção define as opções do compilador TypeScript, como se fossem as instruções específicas na partitura:

  • module: Define o sistema de módulos a ser utilizado, como commonjs, amd, system, etc.
  • noImplicitAny: Gera erros em expressões e declarações com um tipo implícito any, garantindo que todos os tipos sejam explicitamente definidos.
  • removeComments: Remove os comentários dos arquivos de saída, como um editor que limpa anotações e observações das partituras finais.
  • preserveConstEnums: Preserva as enumerações const nos arquivos gerados, garantindo consistência.
  • sourceMap: Gera arquivos .map correspondentes a cada arquivo .js gerado, permitindo a depuração dos arquivos TypeScript originais, como um índice detalhado para facilitar a navegação na sinfonia.

files

Especifica uma lista de arquivos individuais a serem incluídos na compilação, similar a uma lista de músicos selecionados para a performance.

include e exclude

  • include: Define padrões globais para incluir arquivos na compilação, como uma série de músicos ou seções da orquestra.
  • exclude: Define padrões globais para excluir arquivos da compilação, filtrando músicos ou seções que ainda estão praticando ou não participam da performance final.

TSConfig Bases

Dependendo do ambiente de execução JavaScript que você pretende usar, pode haver uma configuração base que você pode utilizar, disponível em github.com/tsconfig/bases. Esses são arquivos tsconfig.json que seu projeto pode estender, simplificando seu tsconfig.json ao lidar com o suporte ao ambiente de execução.

Por exemplo, se você estiver escrevendo um projeto que usa Node.js versão 12 e superior, pode usar o módulo npm @tsconfig/node12:

{
  "extends": "@tsconfig/node12/tsconfig.json",
  "compilerOptions": {
    "preserveConstEnums": true
  },
  "include": ["src/**/*"],
  "exclude": ["**/*.spec.ts"]
}

Isso permite que seu tsconfig.json se concentre nas escolhas únicas para o seu projeto, e não em toda a mecânica do tempo de execução. Já existem algumas bases tsconfig, e esperamos que a comunidade possa adicionar mais para diferentes ambientes.

Detalhes

A propriedade compilerOptions pode ser omitida, caso em que os padrões do compilador são usados. Veja nossa lista completa de opções de compilador suportadas no TSConfig Reference.

TSConfig Reference

Para saber mais sobre as centenas de opções de configuração, consulte a TSConfig Reference.

Schema

O esquema do tsconfig.json pode ser encontrado na JSON Schema Store.

Propriedades Essenciais para projetos angular no tsconfig.json:

lib: [“ES2022”, “dom”]

  • ES2022: Especifica que seu projeto pode usar recursos da versão ECMAScript 2022 (ES2022) do JavaScript. Isso inclui novidades como métodos de array (at), operadores lógicos (&&=, ||=, ??=), e mais. Exemplo:
const array = [1, 2, 3];
const lastItem = array.at(-1); // Retorna 3 (graças ao ES2022)
const foo = Array.prototype.at; // ES2022 feature
  • dom: Indica que seu projeto interage com o Document Object Model (DOM) do navegador. Isso permite que o TypeScript reconheça elementos HTML, eventos e outras APIs do navegador. Exemplo:
document.addEventListener('click', (event) => {
    console.log('Clique detectado!', event);
});
const div = document.createElement('div'); // DOM feature

target: “ES2022”

  • Define a versão do ECMAScript para a qual o TypeScript irá compilar seu código. Ao definir como “ES2022”, o código gerado será compatível com ambientes que suportam essa versão ou posteriores. Se você usar recursos do ES2022 e o ambiente de execução não suportar, o TypeScript fará o “transpile” para uma versão mais antiga.
const data = await fetch('https://api.example.com/data'); // ES2022 feature

module: “ES2022”

A propriedade "module" especifica o sistema de módulos que será utilizado no código de saída.

"ES2022": Indica que o TypeScript deve emitir módulos compatíveis com o ES2022. Isso significa que o código será gerado usando import e export, conforme a especificação dos módulos ECMAScript.

import { myFunction } from './myModule';
export const anotherFunction = () => {};

outDir: “./dist/out-tsc”`

  • Define o diretório onde o TypeScript colocará os arquivos JavaScript compilados. Em projetos Angular, geralmente é “./dist/out-tsc” ou algo similar.

strict: true

  • Ativa um conjunto de regras de verificação de tipo mais rigorosas, ajudando a encontrar erros em tempo de desenvolvimento e a escrever um código mais seguro e previsível.

"strict": true: Ativa todas as verificações estritas, como strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, entre outras.

// Com strictNullChecks ativado, o seguinte código gerará um erro:
let name: string = null; // Error: Type 'null' is not assignable to type 'string'.

// Com strictPropertyInitialization ativado, o seguinte código gerará um erro:
class Person {
  name: string; // Error: Property 'name' has no initializer and is not definitely assigned in the constructor.
  constructor() {}
}

moduleResolution: “node”`

  • Define como o TypeScript irá procurar por módulos importados. “node” segue a resolução de módulos do Node.js, que é o padrão em projetos Angular.

baseUrl: “./”`

  • Estabelece um diretório base para resolver caminhos de módulos não relativos. Geralmente é a raiz do seu projeto.

paths:

  • Permite criar aliases para caminhos de importação, tornando-os mais curtos e fáceis de gerenciar. Exemplo:
"paths": {
    "@app/*": ["src/app/*"],
    "@env/*": ["src/environments/*"]
}

"esModuleInterop": true

Permite compatibilidade entre módulos CommonJS e módulos ES6.

  • "esModuleInterop": true: Habilita a sintaxe de importação padrão (import defaultExport from "module") para módulos CommonJS.
import express from 'express'; // Import de um módulo CommonJS usando sintaxe ES6

Conclusão

O tsconfig.app.json é um componente essencial na configuração de um projeto Angular, permitindo ajustes específicos para a compilação da aplicação. Ele complementa o tsconfig.json, herdando suas configurações e adicionando opções específicas, promovendo uma configuração flexível e modular. Compreender a relação entre esses arquivos e como utilizá-los eficazmente é crucial para otimizar o processo de construção e manutenção de aplicações Angular.