Se você tiver uma base de código TypeScript em um monorepo que não está usando o destino referências do projeto TypeScript então você está perdendo um truque.
As referências do projeto TypeScript existem desde o TypeScript 3.0 e permitem que você especifique os pacotes dependentes no tsconfig.json
dos quais o pacote atual depende. Quando você constrói um pacote com dependências, as dependências são construídas primeiro.
O tsconfig.json
abaixo especifica que este pacote faz referência a um pacote comum
e que o pacote comum
é construído antes do pacote atual:
{ "extends":"../tsconfig-base.json", "compilerOptions": { "outDir":"../lib/animals", "rootDir":".", }, "referências": [ {"caminho":"../core"} ] }
As referências do projeto são especificadas por meio de uma matriz de objetos referências
com uma propriedade path
. A propriedade path
é um caminho relativo para um local diferente contendo um arquivo tsconfig.json
.
Se o projeto não estivesse usando referências de projeto, todos os pacotes teriam que ser construídos individualmente, o que pode ser uma grande chatice se houver vários pacotes dependentes.
Construindo incrementalmente
A opção -b
ou --build
é adicionada ao tsc compilador ao transpilar um pacote que tem referências de projeto:
> tsc-b # Use o tsconfig.json no diretório atual > tsc-b src # Use src/tsconfig.json > tsc-b foo/prd.tsconfig.json bar # Use foo/prd.tsconfig.json e bar/tsconfig.json
Uma compilação bem-sucedida produzirá um tsconfig.tsbuildinfo
, usado em compilações subsequentes para garantir que apenas um novo código ou código alterado seja compilado para um tempo de compilação mais rápido. O arquivo tsconfig.tsbuildinfo
contém as assinaturas e carimbos de data/hora de todos os arquivos necessários para construir o projeto inteiro. Em compilações subsequentes, o TypeScript usará essas informações para detectar a maneira menos dispendiosa de verificar o tipo e emitir alterações em seu projeto.
Observe todos os pacotes no monorepo quanto a alterações
O que realmente impulsionou meu desenvolvimento em TypeScript é a capacidade de fazer o tsc
observar as mudanças em cada pacote de um monorepo.
Tenho um script como este em execução o tempo todo que estou desenvolvendo:
"watch":"tsc-b./tsconfig.packages.json--watch"
Quando o script watch
está em execução, qualquer alteração do TypeScript em todo o monorepo resultará em uma nova construção eficiente:
Estrutura do projeto Monorepo
Na maioria dos monorepos, os nós de pacote individuais estão em uma pasta chamada pacotes
. Abaixo está um exemplo de monorepo com os vários arquivos tsconfig.json
estrategicamente colocados com precisão cirúrgica:
tsconfig.base.json # base tsconfig.json que todos os pacotes irão estender tsconfig.packages.json # tsconfig.json que é usado para assistir a tudo todos os pacotes /package.json /pacotes /common # Utitliies comuns usados por todos os pacotes /src .index.ts # ponto de entrada para o pacote /tsconfig.json # Arquivo de configuração do projeto'comum' /package.json /web # Depende de'comum' /src .index.ts # ponto de entrada para o pacote /tsconfig.json # Arquivo de configuração do projeto'web' /api # Depende de'comum' /src .index.ts # ponto de entrada para o pacote /tsconfig.json # Arquivo de configuração para o projeto'api' /package.json
Na pasta raiz está um arquivo tsconfig.base.json
que é estendido por todos os pacotes no monorepo:
{ "compilerOptions": { "baseUrl":".", "composto": verdadeiro, "declaração": verdadeiro, "declaraçãoMap": verdadeiro, "caminhos": { "common": ["packages/common/src"], "web": ["packages/web/src"], "api": ["packages/api/src"] } } }
Na verdade, há muita coisa acontecendo aqui:
-
"composite": true
instruitsc
que existem referências de projeto -
"statementMap": true
adiciona mapas de origem para arquivos de declaração.d.ts
. SignificaIr para definição
no código VS e irá para o arquivo real e não para o arquivo.d.ts
- O campo
caminhos
contém um objeto com cada chave de objeto (comum, web ou API neste exemplo) apontando para a localização de um pacote. Com este conjunto, podemos importar pacotes sem um caminho relativo ou absoluto desagradável.
por exemplo.import {a} from'web';
Neste exemplo, cada pacote estende tsconfig.base.json
usando a opção extends
de tsconfig
:
{ "extends":"../tsconfig-base.json", "compilerOptions": { "rootDir":".", }, "referências": [ {"caminho":"../core"} ] }
Observando e construindo
O tsconfig.packages.json
na raiz da estrutura do projeto faz referência a todos os pacotes que queremos observar ou construir:
{ "arquivos": [], "referências": [ { "path":"./packages/common" }, { "caminho":"./packages/web" }, { "caminho":"./packages/api" } ] }
Com essa estrutura em vigor, agora podemos construir todos os pacotes de uma só vez:
tsc-b./tsconfig.packages.json
ou assista:
tsc-b./tsconfig.packages.json
Interruptores úteis
As seguintes opções são úteis ao trabalhar com referências de projeto:
--verbose: Imprime um registro detalhado para explicar o que está acontecendo (pode ser combinado com qualquer outro sinalizador) --dry: Mostra o que seria feito, mas não constrói nada --clean: Exclui as saídas dos projetos especificados (pode ser combinado com--dry) --force: age como se todos os projetos estivessem desatualizados --watch: modo de observação (não pode ser combinado com qualquer sinalizador, exceto--verbose)
Webpack
Bundlers como webpack e Rollup não oferecem suporte para referências de projeto há algum tempo, e Rollup tem suporte apenas parcial. Isso não ajudou na adoção.
webpack ts-loader
Ao configurar o webpack loader ts-loader
, você precisa definir a opção projectReferences
como true:
{ teste:/\.tsx?$/, usar: { carregador:'ts-loader', opções: { projectReferences: true, }, }, },
Epílogo
Atualmente, faço a maior parte do meu desenvolvimento principal em monorepo’s, tanto em projetos de clientes quanto no meu próprio desenvolvimento pessoal. Se eu usar o TypeScript como minha linguagem principal, habilitarei as referências do projeto exatamente como descrevi aqui. Acho que são um grande aumento de produtividade que nem todo mundo está usando.
A postagem Aumente sua produtividade com referências de projetos TypeScript apareceu primeiro no LogRocket Blog .