Pular para o conteúdo

Projetos TypeScript

O gerador de projetos TypeScript pode ser usado para criar bibliotecas ou aplicações modernas em TypeScript configuradas com melhores práticas como ECMAScript Modules (ESM), project references do TypeScript, Vitest para execução de testes e Biome para linting e formatação.

Você pode gerar um novo projeto TypeScript de duas formas:

  1. Instale o Nx Console VSCode Plugin se ainda não o fez
  2. Abra o console Nx no VSCode
  3. Clique em Generate (UI) na seção "Common Nx Commands"
  4. Procure por @aws/nx-plugin - ts#project
  5. Preencha os parâmetros obrigatórios
    • Clique em Generate
    ParâmetroTipoPadrãoDescrição
    name Obrigatóriostring-Nome do projeto TypeScript
    directory stringpackagesDiretório pai onde a biblioteca é colocada.
    subDirectory string-O subdiretório onde a biblioteca é colocada. Por padrão, este é o nome da biblioteca.
    preferInstallDependencies booleantrueSe deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao executar múltiplos geradores em lote (uma instalação ainda é executada se necessário para que geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final.

    O gerador criará a seguinte estrutura de projeto no diretório <directory>/<name>:

    • Directorysrc Código-fonte TypeScript
      • index.ts
    • package.json Manifesto do projeto definindo o nome do pacote e dependências do projeto
    • project.json Configuração do projeto e targets de build
    • tsconfig.json Configuração base do TypeScript para este projeto (estende o tsconfig.base.json da raiz do workspace)
    • tsconfig.lib.json Configuração do TypeScript para sua biblioteca (código de runtime ou empacotado)
    • tsconfig.spec.json Configuração do TypeScript para seus testes
    • vitest.config.mts Configuração do Vitest

    Você também notará alterações nos seguintes arquivos na raiz do workspace:

    • nx.json A configuração do Nx é atualizada para configurar o plugin @nx/js/typescript para seu projeto
    • tsconfig.base.json Um alias do TypeScript é configurado para seu projeto permitindo sua importação por outros projetos no workspace
    • tsconfig.json Uma referência de projeto TypeScript é adicionada para seu projeto

    Adicione seu código TypeScript no diretório src.

    Como seu projeto TypeScript é um ES Module, certifique-se de escrever suas instruções de importação com a sintaxe ESM correta, referenciando explicitamente a extensão do arquivo:

    index.ts
    import { sayHello } from './hello.js';

    O ponto de entrada do seu projeto TypeScript é src/index.ts. Você pode adicionar exports aqui para qualquer elemento que deseja que outros projetos possam importar:

    src/index.ts
    export { sayHello } from './hello.js';
    export * from './algorithms/index.js';

    TypeScript aliases para seu projeto são configurados no tsconfig.base.json do workspace, permitindo que você referencie seu projeto TypeScript de outros projetos TypeScript:

    packages/my-other-project/src/index.ts
    import { sayHello } from '@my-scope/my-library';

    Quando você adiciona uma instrução de importação para um novo projeto em seu workspace pela primeira vez, provavelmente verá um erro em seu IDE similar ao abaixo:

    Erro de importação
    Terminal window
    File '/path/to/my/workspace/packages/my-library/src/index.ts' is not under 'rootDir' '/path/to/my/workspace/packages/my-consumer'. 'rootDir' is expected to contain all source files.
    File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6059)
    File '/path/to/my/workspace/packages/my-library/src/index.ts' is not listed within the file list of project '/path/to/my/workspace/packages/my-consumer/tsconfig.lib.json'. Projects must list all files or use an 'include' pattern.
    File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6307)

    Isso ocorre porque uma project reference ainda não foi configurada, e o projeto importado ainda não foi declarado como uma dependência de workspace no package.json do seu projeto.

    Seu workspace está configurado com geradores de sincronização que gerenciam ambos para você, então você não precisa configurá-los manualmente. Basta executar o seguinte comando e o Nx adicionará a configuração necessária:

    Terminal window
    pnpm nx sync
    Terminal window
    NX The workspace is out of sync
    [@nx/js:typescript-sync]: Some TypeScript configuration files are missing project references to the projects they depend on, contain stale project references, or have duplicate project references.
    [@aws/nx-plugin:ts#sync]: Local project dependencies are out of sync. The following workspace dependencies will be declared:
    packages/my-other-project/package.json:
    - @my-scope/my-library: workspace:*
    Syncing the workspace...
    The workspace was synced successfully!

    O gerador TypeScript sync do Nx adiciona a referência de projeto, e o gerador ts#sync do plugin declara o projeto importado no package.json do seu projeto (workspace:* onde o gerenciador de pacotes suporta o protocolo de workspace, * no npm e yarn classic), para que o gerenciador de pacotes vincule o projeto local na instalação. Após isso, o erro em seu IDE deve desaparecer e você estará pronto para usar sua biblioteca.

    Se você adicionar entradas personalizadas em compilerOptions.paths no tsconfig.json de um projeto, o TypeScript para de herdar os aliases do workspace definidos em tsconfig.base.json. O gerador oculto ts#sync é executado antes do target compile (configurado em nx.json) para copiar quaisquer aliases base ausentes nos arquivos tsconfig.json, tsconfig.lib.json e tsconfig.app.json que já declaram paths. Para desativar, remova @aws/nx-plugin:ts#sync de targetDefaults.compile.syncGenerators em nx.json.

    Cada projeto TypeScript declara suas dependências de runtime de terceiros em seu próprio package.json. Ferramentas de build e teste compartilhadas entre projetos são definidas no package.json raiz.

    Para adicionar uma dependência de runtime a um projeto, instale-a nesse projeto:

    Terminal window
    pnpm add some-npm-package --filter my-library

    Você também pode executar o comando add/install simples do seu gerenciador de pacotes de dentro do diretório do projeto.

    Para adicionar uma ferramenta de dev compartilhada, instale-a na raiz do workspace:

    Terminal window
    pnpm add -Dw some-dev-tool

    Para gerenciadores de pacotes que suportam catálogos (pnpm, yarn e bun), os geradores registram cada versão no catálogo e a referenciam com o protocolo catalog: (ex. "zod": "catalog:"), então o catálogo é a única fonte de verdade para versões independentemente de qual projeto declara a dependência. Isso ajuda você a seguir uma política de versão única, evitando conflitos de tipo e múltiplas cópias de pacotes em bundles de implantação.

    Quando você adicionar uma nova dependência, mantenha-a no catálogo também:

    O workspace define catalogMode: strict, então pnpm add registra a versão no catálogo e a referencia automaticamente — sem etapas extras.

    Terminal window
    pnpm add some-npm-package --filter my-library

    Catálogos são habilitados por padrão. Para desativá-los, crie seu workspace com --catalog false:

    Terminal window
    pnpm create @aws/nx-workspace my-project --catalog false

    Ou configure em aws-nx-plugin.config.mts a qualquer momento:

    aws-nx-plugin.config.mts
    export default {
    packageManager: {
    catalogs: false,
    },
    } satisfies AwsNxPluginConfig;

    Com catálogos desabilitados, os geradores escrevem versões de dependências diretamente no package.json de cada projeto, e manter versões alinhadas entre projetos é sua responsabilidade.

    Se você preferir declarar todas as dependências apenas no package.json raiz (sem declarações de dependências por projeto), desative a regra de lint no biome.json do workspace:

    biome.json
    {
    "linter": {
    "rules": {
    "correctness": {
    "noUndeclaredDependencies": "off"
    }
    }
    }
    }

    Projetos resolvem pacotes instalados na raiz em tempo de build, então tudo ainda compila — você abre mão de manifestos por projeto como um registro preciso das dependências de cada projeto (o que importa se você posteriormente publicar um projeto ou dividir o repositório).

    Ao usar seu projeto TypeScript como código de runtime (por exemplo, como handler de uma função AWS Lambda), recomenda-se usar uma ferramenta como Rolldown para empacotar seu projeto, pois isso permite tree-shake para incluir apenas as dependências realmente utilizadas.

    Você pode alcançar isso adicionando um target como o seguinte em seu arquivo project.json:

    {
    ...
    "targets": {
    ...
    "bundle": {
    "cache": true,
    "executor": "nx:run-commands",
    "outputs": ["{workspaceRoot}/dist/packages/my-library/bundle"],
    "options": {
    "command": "rolldown -c rolldown.config.ts"
    }
    },
    },
    }

    E adicionando o arquivo rolldown.config.ts como segue:

    rolldown.config.ts
    import { defineConfig } from 'rolldown';
    export default defineConfig([
    {
    input: 'src/index.ts',
    output: {
    file: '../../dist/packages/my-library/bundle/index.js',
    format: 'cjs',
    inlineDynamicImports: true,
    },
    },
    ]);

    Seu projeto TypeScript está configurado com um target build (definido em project.json), que pode ser executado via:

    Terminal window
    pnpm nx build <project-name>

    Onde <project-name> é o nome totalmente qualificado do seu projeto.

    O target build irá compilar, lintar e testar seu projeto.

    A saída do build pode ser encontrada na pasta dist da raiz do workspace, dentro de um diretório para seu pacote e target, por exemplo dist/packages/<my-library>/tsc

    Para construir todos os projetos em seu workspace, execute:

    Terminal window
    pnpm nx run-many --target build

    Ou use o comando abreviado:

    Terminal window
    pnpm build

    Vitest está configurado para testar seu projeto.

    Testes devem ser escritos em arquivos .spec.ts ou .test.ts, colocalizados na pasta src do seu projeto.

    Por exemplo:

    • Directorysrc
      • hello.ts Código-fonte da biblioteca
      • hello.spec.ts Testes para hello.ts

    O Vitest fornece sintaxe similar ao Jest para definir testes, com utilitários como describe, it, test e expect.

    hello.spec.ts
    import { sayHello } from './hello.js';
    describe('sayHello', () => {
    it('deve cumprimentar o chamador', () => {
    expect(sayHello('Darth Vader')).toBe('Hello, Darth Vader!');
    });
    });

    Para mais detalhes sobre como escrever testes e funcionalidades como mock de dependências, consulte a documentação do Vitest

    Testes serão executados como parte do target build do seu projeto, mas você também pode executá-los separadamente usando o target test:

    Terminal window
    pnpm nx test <project-name>

    Você pode executar um teste individual ou suite de testes usando a flag -t do Vitest. Passe-a após um separador -- para que o Nx a encaminhe ao Vitest ao invés de consumi-la como sua própria opção --target:

    Terminal window
    pnpm nx test <project-name> -- -t 'sayHello'

    Projetos TypeScript usam Biome para linting e formatação. O Biome é configurado no arquivo biome.json da raiz do workspace — alterações aqui se aplicam a todos os projetos TypeScript no workspace garantindo consistência.

    Para invocar o linter e verificar seu projeto, execute o target lint:

    Terminal window
    pnpm nx lint <project-name>

    A maioria dos problemas de lint ou formatação podem ser corrigidos automaticamente executando com o argumento --configuration=fix.

    Terminal window
    pnpm nx lint <project-name> --configuration=fix

    Similarmente, se desejar corrigir todos problemas de lint em todos pacotes do workspace, execute:

    Terminal window
    pnpm nx run-many --target lint --all --configuration=fix

    Para evitar que problemas de lint atrasem você durante o desenvolvimento (particularmente se você tem problemas não corrigíveis automaticamente em seu projeto), você pode executar um build com a configuração skip-lint:

    Terminal window
    pnpm nx run-many --target build --configuration=skip-lint

    Isso pula o target de lint completamente durante o build.