Typescript: tsc não deve se importar e falhar com arquivos ts fora de rootDir

Criado em 21 jul. 2016  ·  87Comentários  ·  Fonte: microsoft/TypeScript

TypeScript: 2.0.0

Eu tenho uma pasta fixtures que contém .ts arquivos. No meu tsconfig.json eu defino rootDir como src que contém todo o meu código-fonte (incluindo o teste).

Os arquivos de fixtures estão lá para casos de teste. tsc não deve reclamar de sua existência e falhar na compilação.

Working as Intended

Comentários muito úteis

Bleh, isso está realmente funcionando como pretendido? Acabei de me deparar com isso, disse à digitação que minha fonte estava toda em uma pasta específica (via rootDir ) e então continuei a _ ignorar completamente o que eu disse_ porque aconteceu de eu ter um único arquivo com um .ts extensão fora dessa pasta.

Isso realmente parece um erro, se eu disser ao compilador onde está meu código-fonte por meio de rootDir , ele não deve desconsiderar completamente essa configuração e alterar minha estrutura de pasta de saída porque pensa que talvez eu tenha feito algo errado. Ele deve apenas ignorar quaisquer arquivos que não estejam em rootDir . Alternativamente, ele deve falhar fortemente, não continuar a emitir saída que não se alinhe com a minha estrutura de pasta de saída desejada!


Para qualquer um que vier atrás de mim, o seguinte fará o que você _realmente_ deseja:

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

Todos 87 comentários

Para contornar, adiciono "excluir" de volta ao meu tsconfig.json

o rootDir é usado para construir a estrutura da pasta de saída. todos os arquivos devem estar em rootDir para que o compilador saiba onde escrever a saída. sem essa restrição, se houver arquivos que não estejam em rootDir, o compilador tem duas opções 1. ou eles serão emitidos em um local totalmente inesperado ou 2. não serão emitidos de forma alguma. Eu diria que uma mensagem de erro é muito melhor do que uma falha silenciosa.

@mhegazy Obrigado pelo esclarecimento. Pelo nome rootDir tomei como o diretório raiz do código-fonte, muito parecido com baseURL para o navegador. Não sabia que é apenas para estrutura de pasta de saída.

Aqui está meu tsconfig.json:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": true,
        "rootDir": "src",
        "outDir": "build"
    },
    "exclude": [
        ".idea",
        "build",
        "node_modules",
        "typings/globals",
        "typings/modules"
    ]
}

Minha estrutura de pastas é parecida com esta:

  • projeto

    • construir

    • node_modules (link simbólico para ../node_modules)

    • node_modules

    • src

Quero que meus arquivos .ts na pasta src sejam compilados e enviados com as mesmas estruturas de pasta para a pasta build. Eu faço isso para poder definir a raiz do meu documento para a pasta de construção e manter meu src fora da raiz do documento. Estou recebendo mensagens de erro sobre arquivos .ts na pasta node_modules, mesmas mensagens de erro que OP. Observe acima, eu excluí node_modules. Por que o tsc está reclamando disso?

@HillTravis, seu problema parece ser o mesmo que https://github.com/Microsoft/TypeScript/issues/9552.

@mhegazy Não tenho certeza se é o mesmo. Sim, minha estrutura inclui um link simbólico, mas qualquer lugar onde esse link existe deve ser ignorado.

Em # 9552, não há pasta src, o que significa que a pasta node_modules existe no caminho que está sendo construído. Em meu cenário, o diretório raiz que tsc deve estar procurando é src, que não contém node_modules. Portanto, ele não deveria estar olhando para aquela pasta. Além disso, excluí explicitamente a pasta node_modules por meio do meu tsconfig.json. Portanto, deve ser duplamente ignorado. Eu também excluí a pasta build , e isso deve cobrir o link simbólico para node_modules dentro dela.

Além disso, em # 9552, não houve menção às mensagens de erro ou à falha na compilação.

Devo também mencionar que estou usando TypeScript 1.8.10.

Especificamente, as mensagens de erro são:

erro TS6059: Arquivo '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.module.ts' não está em 'rootDir' '/ Users / thill / Projects / nrc / client / src '. Espera-se que 'rootDir' contenha todos os arquivos de origem.

erro TS6059: Arquivo '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.ts' não está em 'rootDir' '/ Users / thill / Projects / nrc / cliente / src '. Espera-se que 'rootDir' contenha todos os arquivos de origem.

erro TS6059: Arquivo '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/timepicker-event-interface.ts' não está em 'rootDir' '/ Users / thill / Projects / nrc / client / src '. Espera-se que 'rootDir' contenha todos os arquivos de origem.

@HillTravis, você pode confiar em mim :) é o nosso tratamento inconsistente de links simbólicos que confunde o compilador. seguimos links simbólicos apenas para resolução de módulo de nó e, em seguida, usamos esse nome como o nome do arquivo; em seguida, executamos uma verificação para ter certeza de que todos os arquivos estão no diretório de origem usando o caminho real, em vez do caminho especificado pelo usuário. e é isso que gera o erro.

Como teste, tentei remover o link simbólico. Na verdade, eu apaguei toda a pasta build . Então executei tsc novamente e ainda vi o erro.

Durante mais testes, tentei comentar a importação no código e os usos desse módulo de nó específico (ng2-datetime) e o erro foi embora. Portanto, é apenas quando tento importar esse módulo de nó que vejo o erro, independentemente do link simbólico.

Se você olhar a fonte desse pacote no GitHub, verá que o arquivo package.json tem o parâmetro "main" definido como "ng2-datetime.js", embora o autor também publicou o arquivo .ts com o mesmo nome. Isso parece estar causando o problema. Se eu criar arquivos .d.ts e excluí-los, o problema desaparece. Ele compilou sem problemas, mesmo depois de adicionar o link simbólico de volta.

Portanto, com todo o respeito, não vejo como esse problema pode estar relacionado ao link simbólico especificamente. Parece que geralmente causa problemas quando o autor inclui os arquivos .ts no pacote.

Você sabe se há alguma solução alternativa para isso? O OP acima disse que contornou isso adicionando "excluir" de volta ao tsconfig.json. Já excluí o diretório, mas ainda estou tentando compilá-lo.

Você sabe se há alguma solução alternativa para isso? O OP acima disse que contornou isso adicionando "excluir" de volta ao tsconfig.json. Já excluí o diretório, mas ainda estou tentando compilá-lo.

Isso pode estar relacionado a outro, mas não consigo encontrar no momento. Ao resolver para um tipo, tsc sempre tenta procurá-lo em node_modules , enquanto ele não está lá (relacionado a typings ).

"tsc não deve se importar e falhar com arquivos ts fora de rootDir" Eu concordo.

Não consigo entender por que o typescript estaria olhando para arquivos JS fora do rootDir, uma vez que é onde toda a fonte deve estar.
A mensagem de erro diz que "espera-se que 'rootDir' contenha todos os arquivos de origem", então nada fora desse diretório deve ser esperado ou considerado um arquivo de origem, no que diz respeito ao TS!

Se isso é "Funcionando como pretendido", qual é exatamente a intenção ou motivação desse comportamento? Existe um caso em que o TS deseja compilar arquivos de origem localizados fora do rootDir?

Por outro lado, adicionar uma seção "incluir" no tsconfig resolve o problema. Quando fornecido com arquivos ou diretórios a serem incluídos, o TS não procura outros arquivos fora deles.

com datilografado 1.8.10

Eu tinha uma pasta node_modules em meu homedir ~/node_modules . A execução de tsc do meu diretório de projeto ~/projects/myProject/ fez com que o typescript reclamasse dos seguintes arquivos

../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/config.d.ts(29,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(36,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(68,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(75,111): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/request.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/services/glacier.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.

muito confuso - embora não saiba por que eu tinha uma pasta de módulos de nó em meu diretório inicial para começar.

@iwllyu você pode verificar seu projeto em [email protected] e registrar um novo problema se ainda estiver tendo problemas.

Ainda tenho o problema com o 2.1.4, embora ele se queixe de um conjunto diferente de arquivos

Using tsc v1.8.10
../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(27,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(34,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(66,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(73,111): error TS1110: Type expected.
Using tsc v2.1.4
../../node_modules/aws-sdk/lib/config.d.ts(38,37): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/request.d.ts(164,16): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/s3/managed_upload.d.ts(15,16): error TS2304: Cannot find name 'Promise'.

Vou criar um projeto para isolar o caso de teste

Bem, eu tentei com um novo projeto e não estava acontecendo. Como este é um projeto mais antigo e já o corrigi removendo a pasta node_modules extra, não vou perder mais tempo tentando recriá-lo. Obrigado pela ajuda!

Sobre este caso. Se tudo que você importa são tipos (como se eu estivesse realmente navegando nessa onda "front-typescript, back-typescript") de fora - talvez o tsc possa distinguir o que estou fazendo?
Estou compartilhando apenas tipos de minhas entidades de back-end - para meu aplicativo de front-end. Saída, claro, sem tipos e importações dessas classes (porque eles são usados ​​apenas para tempo de compilação e intellisense).

Tive isso também.
O texto datilografado é muito restritivo para nossa equipe - considerando o fluxo agora.

pessoal, alguma resolução sobre isso agora? usando tipos do código do cliente dentro do código de back-end e de outra forma.

qual é a melhor opção? copiar, colar aqui e ali e modificar se eu alterar os tipos?

fazer um diretório raiz para 2 projetos não é uma opção, pois o backend tsconfig.json terá informações sobre jsx e compilará em commonjs quando eu puder usar es2015

baseUrl funciona para você?

@unional não mudará baseUrl quebrará todas as importações de node_modules - exigindo não escrever

import * as request from "superagent";

mas

import * as request from "node_modules/superagent/..something";

?

Bleh, isso está realmente funcionando como pretendido? Acabei de me deparar com isso, disse à digitação que minha fonte estava toda em uma pasta específica (via rootDir ) e então continuei a _ ignorar completamente o que eu disse_ porque aconteceu de eu ter um único arquivo com um .ts extensão fora dessa pasta.

Isso realmente parece um erro, se eu disser ao compilador onde está meu código-fonte por meio de rootDir , ele não deve desconsiderar completamente essa configuração e alterar minha estrutura de pasta de saída porque pensa que talvez eu tenha feito algo errado. Ele deve apenas ignorar quaisquer arquivos que não estejam em rootDir . Alternativamente, ele deve falhar fortemente, não continuar a emitir saída que não se alinhe com a minha estrutura de pasta de saída desejada!


Para qualquer um que vier atrás de mim, o seguinte fará o que você _realmente_ deseja:

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

Eu disse ao typescript que minha fonte estava toda em uma pasta específica (via rootDir)

Não é isso que rootDir significa! rootDir significa "Use esta pasta como base relativa para calcular os caminhos em outDir ". Quais arquivos fazem parte da sua compilação é uma pergunta separada que é respondida por files e / ou include / exclude

Mesmo que eu aceite isso, o comportamento atual ainda é um erro IMO. Se eu tiver algum arquivo TS fora do diretório especificado, rootDir _não_ será a base para calcular os caminhos em outDir , o que significa que a configuração especificada será completamente ignorada.

Acho que falhar seriamente seria muito melhor porque o compilador efetivamente pensa que dei uma configuração inválida. Ignorar a configuração quando ela é inválida (IMO) não é a maneira certa de lidar com essa classe de falha.

Exemplo de mensagem de erro que seria muito mais clara (junto com falha grave):

O TSC encontrou arquivos typescript fora de rootDir e, portanto, não pode prosseguir com a compilação. Altere rootDir para incluir todos os arquivos typescript ou exclua arquivos fora de rootDir, ou inclua apenas arquivos dentro de rootDir.

Nota: Uma grande parte do motivo pelo qual o comportamento atual de rootDir parece muito errado é precisamente porque não faz sentido ter arquivos fora de rootDir. Quando alguém se pergunta a si mesmo (ou ao compilador) o que significa compilar arquivos fora de rootDir a única resposta é "não faz sentido". Portanto, chega-se à conclusão natural de que rootDir também especifica sourceDir.

O mal está na nomeação. Isso realmente significa relativePathBaseDir ou algo parecido.

Também notei que include normalmente significa "olhe aqui também", mas neste caso significa "apenas olhe aqui".
Seria sensato que tivesse outro nome e fosse obrigatório.

IMO, este comentário deve ser especialmente levado em consideração para confirmar que este é realmente um bug e deve ser reaberto como tal:

Nota: Uma grande parte do motivo pelo qual o comportamento atual de rootDir parece muito errado é precisamente porque não faz sentido ter arquivos fora de rootDir. Quando alguém se pergunta a si mesmo (ou ao compilador) o que significa compilar arquivos fora de rootDir a única resposta é "não faz sentido".

Na verdade, isso não faz sentido . "Arquivos de origem fora de rootDir " simplesmente não são arquivos de origem , não importa sua extensão ou conteúdo. O compilador nunca os compilará. Então, por que ele reclama da existência deles? Ele está com ciúme por haver arquivos que não estão sob seu comando?

+100 sobre isso ser um bug (desagradável, na verdade). Considere a seguinte estrutura de diretório:

- src/
  - module.ts
- test/
  - module.test.ts
- out/
  - module.js

Eu gostaria que tsc compilasse apenas src , porque eu executo testes com ts-node . Ter rootDir: 'src' causará um erro de compilação no momento. Se você marcar os testes e outras coisas que pretende executar apenas com ts-node (ou até mesmo compilar separadamente, talvez?) Como "excluídos", coisas ruins começam a acontecer (por exemplo, o destaque do vscode quebra nos testes )

Na verdade, nenhuma combinação de rootDir , excluded e todas as outras opções satisfaz todos os requisitos (exclua os testes da compilação, embora ainda seja capaz de executá-los e trabalhar com eles).

E eu realmente não acho que meu caso de uso seja único, então vale a pena reconsiderar o rótulo "funcione conforme planejado" pelo menos do ponto de vista da UX.

A configuração src / test / out foi um cenário chave abordado por referências de projeto

Encontrei esse problema porque estava pesquisando por que o typescript estava tentando compilar meu arquivo webpack.config.js depois de definir rootDir .

Eu disse ao typescript que minha fonte estava toda em uma pasta específica (via rootDir)

Não é isso que rootDir significa! rootDir significa "Use esta pasta como base relativa para calcular os caminhos em outDir". Quais arquivos fazem parte da sua compilação é uma pergunta separada que é respondida por arquivos e / ou inclusão / exclusão

Esta é a resposta! Os documentos para rootDir dizem

Especifica o diretório raiz dos arquivos de entrada

O que eu entendi como "arquivos de _source_ de entrada". Eu recomendo que o comentário de @RyanCavanaugh substitua a explicação atual para esta opção.

Link aqui - https://github.com/Microsoft/TypeScript/issues/11299 é uma duplicata deste problema. (Solução: use incluir / excluir para especificar arquivos a compilar, rootDir NÃO especifica quais arquivos compilar.)

@mhegazy Você adicionaria um comentário nesse tópico para esse efeito? Parece ser a isso que o autor da pergunta está se referindo (confuso sobre por que o TS está olhando para qualquer arquivo fora do RootDir, mesmo mal-entendido sobre o que significa rootDir).

Também estou enfrentando esse problema e não consegui resolvê-lo.

A compilação tsc está levando a árvore do meu diretório incluído para as pastas-pai, causando erros de tipo duplicado.

Eu tenho uma estrutura de pasta aninhada que se parece com esta:

└─src
└─package.json
└─node_modules
└─tsconfig.json
└─example
│ └─src
│ └─package.json
│ └─node_modules
│ └─tsconfig.json

Agora, quando tento executar o tsc de dentro do diretório de exemplo, recebo o seguinte erro:

node_modules/@types/react/index.d.ts:2809:14 - error TS2300: Duplicate identifier 'LibraryManagedAttributes'.

2809         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                  ~~~~~~~~~~~~~~~~~~~~~~~~

  ../node_modules/@types/react/index.d.ts:2814:14
    2814         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                      ~~~~~~~~~~~~~~~~~~~~~~~~
    'LibraryManagedAttributes' was also declared here.

Como você pode ver pelo erro, tsc está movendo a árvore para cima e para fora da pasta de exemplo, e procurando na pasta node_modules do diretório pai! O que parece ainda pior é que tentei ignorar explicitamente o diretório pai node_modules com pouco efeito.

Aqui está o tsconfig do diretório de exemplo:

{
  "compilerOptions": {
    "target": "es5",
    "experimentalDecorators": true,
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "lib": ["es2017", "dom"],
    "jsx": "react"
  }
,
  "typeRoots": [
    "./node_modules/@types"
  ],
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "../node_modules"
  ]
}

Como posso resolver esse problema? Nenhuma das opções acima parece funcionar para mim

@lexwebb Eu tive o mesmo problema, verifique em seus yarn.lock arquivos se @types/react tem as mesmas versões.
Consulte https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes.

Eu pousei aqui porque minha pasta de ativos contém um arquivo de vídeo "MPEG Transport Stream" com extensão .ts então fez o tsc travar mesmo se a pasta não estivesse no meu caminho rootDir 😄

Eu corrigi ao adicionar a pasta de ativos nos caminhos exclude , mas era um comportamento perturbador 🤔

Acontece que eu tinha uma versão ligeiramente diferente de react tanto no pacote json pai quanto no filho. A correspondência exata das versões removeu o problema. Ainda é uma dor que você não pode excluir a verificação de tipo de formulário dos diretórios pai.

Acho que isso nunca vai ser consertado. Acabei de ter o mesmo problema. Como isso "funciona como pretendido" está além da minha compreensão. Acho que a intenção era fazer o compilador rodar de uma maneira absurda.

De minha própria experiência pessoal, a razão pela qual uma compilação datilografada sai de sua árvore rootDir e tenta construir coisas que você não esperava é o fato de você ter (deliberadamente ou inadvertidamente) referenciado direta ou indiretamente algo nesse área de dentro de sua rootDir . Se você fizer isso, a construção seguirá a árvore de referência, independentemente de você ter tentado ou não excluir a área que contém o arquivo referenciado. Às vezes pode ser um PITA tentando descobrir como / onde você fez isso - mas invariavelmente eu acho que é minha própria culpa - não é culpa de tsc . É apenas fazer o que eu disse para fazer.

Sempre que isso me atinge, é por causa dos tipos. Eu importo uma interface ou algo que reside em um arquivo que importa outra coisa que reside em um arquivo que importa outra coisa ...... até que eventualmente acabo importando algo que reside em um arquivo fora do meu rootDir e muitas vezes em algo que estou tentando excluir explicitamente em minha configuração.

HTH alguns de seus chegam à raiz de sua dor. Nenhuma configuração o tirará disso - você apenas precisa manter um controle estrito de sua estrutura de importação.

@kpturner Isso parece muito razoável, mas - um projeto de teste

Mesmo? Que eu nunca vi :)

As pastas excluídas são sempre excluídas em todos os meus projetos, exceto quando as circunstâncias às quais aludo estão presentes.

Existem exemplos básicos neste tópico? Difícil dizer pelo meu telefone.

Desculpas, a exclusão não faz parte da situação de 'esqueleto' a que me refiro. Estou apenas observando que as importações não parecem ser a causa do comportamento (embora faria mais sentido se fosse o caso).

ou seja, compilar algo assim resultará em um erro.

-src / src.ts <- no imports -test / test.ts -out -tsconfig.json {"rootDir": "src", "outDir": "out"}

Mas se seu tsconfig.json parecer com isso, eu esperaria que o typescript compilar tudo no diretório src e tudo no diretório test . Se você quiser apenas transpilar apenas coisas em src e enviar para o diretório out , então seu tsconfig.json deve ser

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    }
}

Em seguida, ele geraria um erro TS6059 porque você tem alguns arquivos fora de rootDir . Então você deve excluir aqueles:

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    },
    "exclude": [
        "test"
    ]
}

que, quando transpilado, irá gerar uma pasta chamada out com a subpasta src contendo src.js . A pasta test é completamente ignorada. Isso é o que eu esperava que acontecesse - não?

Er, de fato, meu exemplo tsconfig deveria ter incluído rootDir e outDir sob compilerOptions como você mostra em seu primeiro exemplo. Você também está correto ao dizer que, ao excluir test , test e seus arquivos são excluídos. Originalmente, pensei que você estava dizendo que um (ou o) culpado do erro TS6059 é um arquivo em rootDir importando algo de fora de rootDir - embora eu ache que o interpretei mal. Independentemente disso, estou de acordo com outros aqui em estar surpreso que diretórios fora de rootDir devem ser explicitamente excluídos conforme você descreve.

Não, eu estava (anteriormente) dizendo que a árvore de referência pode resultar em coisas sendo transpiladas em sua lista de excluídos - um pouco diferente.

O erro do TS6059 é um pouco desconcertante no início - mas eu o vejo como um TS tentando me impedir de cometer erros. Se eu tive o trabalho de definir um rootDir e então o plonk datilografado voa para fora desse rootDir, então o TS está efetivamente dizendo "oi - você criou o texto datilografado que não consigo acessar - está certo?"

Eu respondo “não, não está certo, estraguei tudo” e movo os arquivos para rootDir
OU
Eu digo “sim, está certo e sinto muito não ter avisado” - e então adiciono à lista de arquivos excluídos.

Isso é muito complicado. Eu tenho um monorepo e não consigo encontrar uma maneira de compilar apropriadamente cada pacote para si mesmo, emitindo a estrutura de diretório correta, ao importar pacotes locais (do mesmo monorepo) usando a opção paths .

A estrutura do diretório no diretório de saída contém pastas pai indesejadas ou o tsc reclama que os arquivos estão fora do diretório raiz.

Não pode ser tão complicado, certo?

Não importa quais opções em qualquer combinação que eu use, tsc parece não ser capaz de lidar com um monorepo com paths fazendo referência a pacotes locais no mesmo monorepo. Eu tentei --build , --project , references , paths , extends , rootDir , rootDirs , include , exclude , baseUrl , outDir em todos os tipos de combinações com valores diferentes e no final reclama que os arquivos não estão dentro de rootDir ou estraga ao emitir uma estrutura de diretório errada dentro de outDir .

Eu não descreveria o que tenho como um monorepo, mas tenho três projetos diferentes no mesmo repo - e posso transpilar cada um independentemente sem problemas ou interferência dos outros. Cada projeto tem seu próprio tsconfig

Depois de algum tempo tentando e mexendo, consegui executar um monorepo com lerna e datilografado . A configuração do texto digitado usa references em combinação com paths e não engasga mais com rootDir .

o rootDir é usado para construir a estrutura da pasta de saída. todos os arquivos devem estar em rootDir para que o compilador saiba onde escrever a saída.

E os arquivos que não requerem saída? Ter um arquivo json fora da raiz:

const errors = require("../../../../errors.json");

Porque não consigo compilar a versão ES6:

import * as errors from "../../../../errors.json";

No entanto, com a primeira versão, estou perdendo a segurança de tipo.

@mhegazy Este problema foi encerrado há 3 anos. No entanto, parece que ainda é uma fonte de confusão 3 anos depois.

Você poderia revisitar o status "Trabalhando conforme pretendido"? Dada a reação da comunidade neste tópico, é bastante seguro dizer que ela não está se comportando como a comunidade espera . Quer seja um problema de documentação, renomeando essa opção, mudando seu comportamento ou adicionando uma nova opção, acredito que há realmente um item de ação do seu lado a ser determinado.

Eu posso entender que você tem prioridades muito mais altas do que esta, mas manter este problema encerrado sem qualquer sinal de que o feedback dado aqui algum dia foi valorizado não transmite uma imagem muito boa para o Typescript, para ser honesto.

@ngryman Qual é o próximo passo que temos? rootDir tem uma definição - esta é a raiz comum dos meus arquivos de origem. Quando um arquivo não está na raiz comum, pela própria definição de rootDir , isso é um erro. Essa definição está documentada. Não posso fazer nada sobre o fato de que as pessoas inventaram suas próprias definições para rootDir e ficam surpresas subsequentemente.

É como ir ao Starbucks e dizer que pedir um café com leite não deve resultar em uma mistura de café expresso com leite vaporizado. É impossível de operar porque você está discutindo com uma definição . Se você quiser uma bebida diferente, peça outra. Se a Starbucks não estiver oferecendo o tipo de bebida que você deseja, dê uma sugestão sobre o que essa bebida deve ser e do que deve ser feita.

Como mencionei em https://github.com/microsoft/TypeScript/issues/9858#issuecomment -370653478, acho que a solução para esse problema é simplesmente uma mensagem de erro melhor. Quando me deparei com ele e finalmente encontrei esse problema do GitHub, minha maior frustração veio de quanto tempo eu perdi tentando descobrir o problema e, em seguida, pensando que era um bug do compilador e, em seguida, criando um caso de reprodução e, em seguida, encontrando um bug duplicado que diz "funcionando conforme o planejado". Falhar rápido com uma mensagem de erro clara teria me salvado de tudo isso.

Se houver arquivos de origem fora de rootDir , isso significa que o projeto TypeScript está configurado incorretamente. Dar ao usuário uma mensagem clara indicando isso, junto com orientações sobre como consertar, acho que resolveria o problema para muitas pessoas.

@RyanCavanaugh Obrigado por sua resposta rápida.

Se eu for para esta página: https://www.typescriptlang.org/docs/handbook/compiler-options.html. Eu li a seguinte definição:

Especifica o diretório raiz dos arquivos de entrada. Use apenas para controlar a estrutura do diretório de saída com --outDir.

Estou literalmente entendendo que é " usado apenas para controlar a estrutura do diretório de saída" e é isso. O " único uso " é importante aqui. Como poderia imaginar que não é a única coisa que o compilador está fazendo na realidade, mas que também emitirá erros se eu tiver arquivos Typescript fora desse diretório.

Talvez esteja faltando alguma coisa, mas se for esse o caso, estou longe de ser o único. Portanto, se você tem um produto e uma boa parte dos usuários não o entende, existem apenas 2 caminhos a seguir: ou você considera seus usuários estúpidos ou não consegue comunicar algo com clareza. Espero que você não esteja inclinado para o primeiro 😕

Para terminar com o exemplo do Starbuck, vamos escrever "mistura de leite expresso e leite no vapor" na lista de ingredientes, para que eu saiba o que é um café com leite e não tenha que adivinhar.

A implicação de um arquivo fora de rootDir seria que o TS geraria um arquivo fora de outDir , o que eu acho que é um comportamento evidentemente ruim.

A mensagem de erro poderia ser melhor - adoraria uma sugestão ou um RP para isso.

Os documentos sempre poderiam ser melhores - mais uma vez, adoraria ideias concretas sobre como comunicar as coisas com mais clareza.

Insinuar que estou chamando as pessoas de estúpidas não é algo que eu gostaria mais.

A implicação de um arquivo fora de rootDir seria que o TS geraria um arquivo fora de outDir, o que eu acho que é um comportamento evidentemente ruim.

Ainda não estou certo sobre por que o compilador simplesmente não "chroot" para rootDir e não considera os arquivos fora desse diretório. Como um usuário, provavelmente sem contexto sobre tsc internos e histórico, este definitivamente não é um comportamento previsível para mim.

Um exemplo que posso dar na minha cabeça é Jest, que oferece a mesma opção: https://jestjs.io/docs/en/configuration#rootdir -string. AFAIK Jest não considera arquivos de teste fora de rootDir . Eu esperaria o mesmo comportamento aqui, por exemplo.

Os documentos sempre poderiam ser melhores - mais uma vez, adoraria ideias concretas sobre como comunicar as coisas com mais clareza.

Fico feliz que você esteja considerando melhorias aqui. A sugestão de @MicahZoltu pode ser interessante de explorar.

De minha parte, posso reafirmar que não acho que rootDir seja previsível (daí a reação das pessoas), mas pelo que entendi, mudar o comportamento dessa opção não é algo a ser considerado. Portanto, como um meio-termo, uma coisa que eu também poderia propor seria renomear rootDir para um nome mais significativo, outBaseDir poderia ser um candidato. Mas provavelmente existe um nome melhor.

Insinuar que estou chamando as pessoas de estúpidas não é algo que eu gostaria mais.

Não insinuei nada e lamento se interpretou assim. Afirmei apenas um fato muito simples: quando os usuários reclamam de algo que não entendem, existem efetivamente apenas 2 caminhos a seguir. Concluí que espero que você não esteja inclinado para o primeiro. O fato de você se associar a um desses caminhos é, honestamente, deixado para você.

Acho que disse o que tinha a dizer, especialmente sobre como dar um feedback sincero sobre como esse tópico foi tratado. Portanto, deixarei espaço para que outros proponham soluções.

@ngryman Eu concordo que a definição de rootDir e o que ele realmente está fazendo não parecem se alinhar. Quando você cria um novo projeto ts (via tsc --init ), o comentário em tsconfig.json para rootDir é semelhante ao que você citou /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ . Se eu fornecer um diretório de arquivos _input_, espero que os únicos que ele vai considerar a compilação estão nesse diretório, pela definição de entrada.

@RyanCavanaugh Pode ter feito sentido relatar um erro como este 4 anos atrás, quando o typescript era usado para ser compilado em javascript. Claro que não quero arquivos perdidos! Mas agora com a popularidade da execução de texto digitado, como ts-node , parece que tsc está com um pouco de inveja para mim.

E a ideia de que os arquivos datilografados fora de rootDir implicam em uma configuração de projeto incorreta é simplesmente errada. Não preciso que meus testes de unidade, que são escritos em typescript, sejam compilados em javascript. ts-node é simplesmente mais rápido e posso aproveitar todos os benefícios da digitação ao escrever testes.

Eu concordo com @CodySchrank . Não há problema em ter um erro de TS quando algum arquivo de origem dentro do rootDir faz referência / importa um arquivo fora dele - isso é esperado.

No entanto, não consigo entender o TypeScript para procurar por si mesmo em arquivos não relacionados fora de rootDir e errar, enquanto esses são simplesmente arquivos de configuração para ferramentas diferentes, como jest ou qualquer outra coisa. Quer dizer, qual é o ponto? Essas nem mesmo são partes do meu aplicativo e não são referenciadas / importadas de qualquer lugar diretamente, e meu Deus, por que eu iria querer que elas fossem agrupadas na compilação resultante em primeiro lugar ...

Eu me pergunto quais seriam as implicações de transformar esse erro em um aviso. Depois de dar uma olhada rápida no código, certamente parece possível, mas definitivamente não sou nenhum especialista no processo de construção de tsc. Parece um meio termo entre nos manter notificados sobre um problema em potencial, mas também nos permitir contorná-lo, se quisermos.

A configuração src / test / out foi um cenário chave abordado por referências de projeto

Isso requer pelo menos uma configuração de projeto separada para cada pasta raiz (https://www.typescriptlang.org/docs/handbook/project-references.html). Depois de ler as instruções, saí sem um bom entendimento de como implementar o padrão e sinto que estou recebendo uma britadeira quando o que solicitei foi um mata-moscas.

Claro, manter módulos adjuntos como subprojetos separados dentro de minha pasta de código-fonte é mais eficiente, mas não estou compilando lodash aqui. O que eu quero é incluir muitos arquivos, como arquivos de teste e benchmark, em uma pasta de projeto comum para análise estática e, quando chegar a hora de compilar, apenas emitir um único diretório para uso do mundo externo. Isso parece fácil de especificar e estou lutando para ver por que não é apenas difícil para o usuário fazer, mas aparentemente _verboten_ da perspectiva das especificações do TS.

O que quero enfatizar é que o único motivo pelo qual esse recurso não é permitido é devido à suposição do compilador de intenção corrompida por parte do desenvolvedor. Quando o desenvolvedor define "outDir" para ./src e o compilador encontra um arquivo TS em ./test , ele _pode_ assumir que este arquivo não precisa ser emitido (assumindo, é claro, que não é referenciado a partir de nenhum arquivo em "outDir").

Mas isso não acontece. Ele assume que o desenvolvedor _queria_ emitir esse arquivo e, por incompetência ou malícia, especificou um subdiretório que não o contém. Em outras palavras, o compilador tem a oportunidade de combinar as instruções do desenvolvedor a um caso de uso comum e razoável e, em vez disso, faz a correspondência com algo absurdo e se recusa a prosseguir.

Do jeito que está, eu nem vejo qual é o caso de uso legítimo para "outDir" . Estou assumindo que é para oferecer suporte a uma estrutura de projeto em que tsconfig.json está no nível superior junto com outros arquivos de configuração e metadados, e o proprietário deseja que a pasta compilada represente apenas a pasta de origem que está aninhada dentro dela. (Certifique-se de que nenhum desses meta-arquivos termina com .ts : isso seria absurdo.)

Parece-me que o design da especificação é antagônico ao usuário. Houve uma referência a pedir uma bebida no Starbucks e ficar chateado quando não era o que se esperava, apesar dos ingredientes estarem listados no menu. Isso é adequado até o fim, mas eu compararia esse recurso mais a uma barraca de cachorro-quente que não vende cachorro-quente.

Claro, os clientes irritados deveriam ter voltado e visto a grande placa proclamando corajosamente que a barraca de cachorro-quente não vende cachorro-quente. Mas, à medida que a confusão se acumula, pode haver uma oportunidade para os donos da barraca de cachorro-quente refletirem sobre como estão comunicando os recursos de seu produto aos clientes.

Hmm, considerando mais isso, eu me pergunto se há um tipo de invariante por parte da equipe principal que está por trás desse problema:

Todo o código-fonte deve ser compilado. Se não for compilado, não é o código-fonte.

No userland, é necessário superar isso de alguma forma. Não sei se fazemos isso estendendo a definição do código-fonte viz. TypeScript ou criando uma segunda categoria (“código de suporte”, “código de validação”, “código periférico” ...). Este seria o código que se espera operar sob as mesmas definições de tipo que a fonte e que deve ser validado com sucesso para que a fonte seja considerada correta, mas que não faz parte da funcionalidade real do programa com relação à sua interface.

Como consumidor do TypeScript, não tenho noção das dificuldades específicas de implementação de tal categoria. No entanto, parece que se encaixaria perfeitamente com "outDir" : qualquer coisa dentro de "outDir" faz parte da fonte, qualquer coisa fora dela, mas dentro da pasta do projeto, faz parte do código de suporte. A principal coisa que torna isso útil / necessário é o advento do ts-node, o que significa que posso executar esse código de suporte como uma etapa separada, completamente independente da compilação; e é claro que quero tirar vantagem disso.

não inclui implicitamente nenhum arquivo de entrada fornecido para a ferramenta

Este problema é causado exatamente _porque_ o usuário está implicitamente tentando compilar arquivos fora de rootDir . Você basicamente disse ao compilador, "compile apenas os arquivos neste diretório" e, em seguida, passou a referenciar os arquivos fora desse diretório. O compilador está confuso e não sabe como proceder.


/project/source/index.ts

import '../external.ts'

/project/tsconfig.json

{
  "compilerOptions": {
    "rootDir": "./source"
  }
}

Neste exemplo, você diz ao compilador "os arquivos fonte estão apenas no diretório 'fonte'". Então, um desses arquivos faz referência a um arquivo que _não_ está no diretório de origem. O TypeScript agora tem duas instruções conflitantes, uma diz para compilar apenas arquivos no diretório de origem, a outra diz para compilar arquivos fora do diretório de origem.

@MattiasMartens você está confundindo implicitamente include e rootDir . Se você tiver /src e /test , se include for src/* então você não pode obter erros sobre as coisas em /test menos que algo de src importou incorretamente algo de test , e você deve ficar feliz com isso!

Não é hostil ao usuário ou antagônico fornecer um mecanismo para escrever a aparência de uma importação incorreta em seu programa e emitir um erro quando tal importação incorreta ocorrer. Mais uma vez, acho que isso vem de um mal-entendido sobre o que os sinalizadores significam - eles são principalmente verificações de aplicação opt-in para ajudá-lo a validar se seu programa está configurado corretamente.


Qualquer forma!

Dada a definição de rootDir , quando o TypeScript vê um arquivo fora do rootDir , ele tem algumas opções:

  • Emita um arquivo acima de outDir (assumindo que isso seja possível!), O que contradiz as instruções do usuário sobre o local de saída
  • Processe o arquivo, mas não o emita, o que, na ausência de outras etapas de compilação, produzirá um programa que não funciona
  • Emita um erro porque o projeto parece estar configurado incorretamente

Oponho-me veementemente à noção de que emitir um programa que .ts arquivos encontrados fora de rootDir como .d.ts , isso é razoável, é apenas uma coisa separada do significado de rootDir algo diferente de rootDir . O que você chamaria de tal bandeira?

@MattiasMartens você está confundindo implicitamente include e rootDir . Se você tiver /src e /test , se include for src/* então você não pode obter erros sobre as coisas em /test menos que algo de src importou incorretamente algo de test , e você deve ficar feliz com isso!

Isso é verdade. Eu mexi em include e descobri que funciona melhor do que pensei para este caso, inclusive com as ferramentas do VSCode.

Eu ainda gostaria de ter um código que seja validado na compilação, mas não emitido na compilação, que é algo que include não cobre. Mas esse é um pedido separado que não precisa ser discutido aqui.

Acho que isso vem de um mal-entendido sobre o que os sinalizadores _ significam - eles são principalmente _ verificações de aplicação opt-in_ para ajudá-lo a validar se seu programa está configurado corretamente.

Estou confuso com isso. Você considera rootDir um cheque de aplicação opt-in? Afeta o que eventualmente é emitido, portanto, claramente não é _somente_ uma verificação de aplicação.

Alguns sinalizadores, como target , mudam drasticamente o que será emitido - não são verificações de aplicação, mas instruções do compilador. rootDir lê como e é documentado como uma instrução do compilador.

Oponho-me fortemente à noção de que _emit a non-working program_ deva ser o padrão.

Pelo que li sobre este tópico até agora, parece haver um amplo consenso de que uma referência de um arquivo dentro de rootDir a um arquivo fora de rootDir _deve ser um erro_. O aspecto do recurso que eu e outros consideramos frustrante é que ele não para por aí, mas na verdade gera um erro se encontrar algum arquivo TS na pasta do projeto fora de rootDir seja um arquivo em rootDir importa ou não.

Vale a pena repetir: eu defini rootDir para a pasta onde meu código-fonte reside, o compilador percebe outro código TS no projeto que não tem rootDir e ele para! Esse comportamento específico não me ajuda a entender meu código. É simplesmente irritante.

É verdade que, da perspectiva da definição do TypeScript de rootDir , conforme elaborado neste tópico, o comportamento é perfeitamente razoável e todos os que vieram aqui para expressar sua frustração sobre isso estão errados. Mas não é razoável com base na definição convencional esperada de um diretório raiz. Eu coloquei para você que em praticamente qualquer contexto onde eu forneça um diretório raiz, estou dizendo ao programa por onde começar a percorrer a estrutura do arquivo, não perguntando se é absolutamente certo que não há algo mais no sistema de arquivos que eu também possa estar interessado em.

As definições podem estar erradas. Eles podem ser alterados. Para compatibilidade com versões anteriores, não é necessário reter as definições, apenas a funcionalidade.

Se a solicitação de recurso aqui é simplesmente tratar .ts arquivos encontrados fora de rootDir como .d.ts

Eu ... acho que não quero isso, basicamente pelas mesmas razões pelas quais quero que o compilador gere um erro quando algo em rootDir importa código de fora dele. Eu realmente acho que o conteúdo de rootDir se eu fornecer um deve ser encapsulado a partir do código ao redor.

Acho que a maneira mais simples de evitar o comportamento que eu e outros não queremos é excluir implicitamente arquivos fora de rootDir se os arquivos em rootDir não se referirem a eles. Se os arquivos em rootDir se referem a eles, um erro deve ser jogado, como é atualmente.

Cada parágrafo parece se resumir a " rootDir deve alterar o valor padrão de include ", o que seria uma coisa razoável a sugerir se estivéssemos adicionando essas sinalizações hoje ao mesmo tempo, mas não é uma alteração decisiva que poderíamos fazer neste momento. Embora, sem dúvida, fazer todos os sinalizadores de configuração interagirem mais entre si aumenta a carga cognitiva em vez de diminuí-la.

Talvez devêssemos apenas emitir um erro personalizado quando include não estiver explicitamente definido e um arquivo incluído estiver fora de rootDir .

O arquivo "tests / foo.ts" está fora de rootDir 'src'. Você se esqueceu de definir um padrão de "inclusão"?

Logged # 33515

Tive problemas com isso, também em https://github.com/microsoft/TypeScript/issues/31757#event -2480427393

A interação entre rootDir, incluir e excluir foi projetada de forma estranha.

Sempre pensei que rootDir é a pasta que o compilador começa a percorrer e incluir pastas adicionais (por exemplo, pastas de fornecedores) que podem ser referenciadas em rootDir.

A definição atual é estranha como o inferno e extremamente não intuitiva.

Ironicamente, o que é confuso é que eles não interagem: as configurações não afetam umas às outras. include está 100% no controle do que está no programa e rootDir está 100% no controle do cálculo do layout de outDir .

Só para adicionar outro exemplo do problema, esta é a estrutura da minha pasta:

tsconfig.json
package.json
src/index.ts

Eu tenho em meu tsconfig:

"rootDir": "src",
"outDir": "lib",

E no meu "index.ts" (pasta src)

import pkg from '../package.json'; // I read the package.json object

export class SomeClass {
  public version = pkg.version;
}

_Sei_ que, após a construção, o arquivo "index.js" estará dentro da pasta "lib". E eu _sei_ que o package.json estará 1 nível acima.
Não acho que o Typescript deva saber melhor do que eu minha estrutura de pastas e quebrar a construção. Ele deve simplesmente registrar um aviso sobre alguns arquivos fora da pasta rootDir que não foram incluídos na pasta de saída.

@sebelga Eu provavelmente consideraria um bug - permitir .json de fora de rootDir seria OK, pois o TS não copia isso para a pasta de saída

@sebelga Eu provavelmente consideraria um bug - permitir .json de fora de rootDir estaria OK, pois o TS não copia isso para a pasta de saída

Obrigado, não é verdade .. Temos algumas regras especiais para a emissão de arquivos .json ... Se o arquivo for emitido no mesmo local em que ele mesmo, então, e só então, ele não será emitido. Em todos os casos, ele é emitido (por exemplo, quando --outDir for especificado, ele será emitido para essa pasta)

@RyanCavanaugh Eu tenho um caso de uso semelhante a @sebelga, onde desejo console.log o número da versão de package.json em tempo de execução.

Então minha solução foi mudar meu "rootDir": "." , então eu tenho isso inclui

"include": [
    "src",
    "typings"
  ]

E como o arquivo package.json está incluído na pasta lib (construída), que contém uma subpasta "src", escrevi um script bash que é executado logo após a construção para limpar as coisas.

#!/bin/bash

rm lib/package.json
mv $(pwd)/lib/src/* $(pwd)/lib
rm -rf lib/src

Funciona, mas parece meio maluco para mim.

@sebelga Você tem .ts arquivos na pasta typings ? Do contrário, seria legal definir rootDir como src e pular o script.

@sebelga Em vez de const { version } require('../../package.json') ou import { version } from 'package.json') , você tentou fazer algo assim:

import { sync as loadJsonFileSync } from 'load-json-file';

const { version } = loadJsonFileSync('../../package.json');

O TypeScript não se importará em estar fora do rootDir dessa maneira.

https://github.com/sindresorhus/load-json-file

Se quiser evitar codificar todos os ../.. você pode tentar isto:
https://github.com/sindresorhus/read-pkg-up

@RyanCavanaugh Não consigo defini-lo como "src" conforme mencionado acima. Estou importando "package.json" fora de nosso src ( import pkg from '../package.json'; ) e tsc não permite isso.

Obrigado por compartilhar este @dylang ! Eu vou tentar isso.

Eu disse ao typescript que minha fonte estava toda em uma pasta específica (via rootDir)

Não é isso que rootDir significa! rootDir significa "Use esta pasta como base relativa para calcular os caminhos em outDir ". _Quais arquivos fazem parte da sua compilação_ é uma pergunta separada que é respondida por files e / ou include / exclude

@RyanCavanaugh Mas é isso que rootDir deve significar, e é disso que se trata.

Não sou muito bom em manter minha compostura quando vejo problemas abertos desde 2016 que provavelmente poderiam ser corrigidos sem a introdução de novos problemas para os usuários existentes, introduzindo um novo "compilerOption" para que o compilador saiba que pode ignorar o erro em um determinado caso de uso.

Por isso, peço desculpas. Não posso evitar, porque devo prestar um bom serviço, mas ocasionalmente encontro tópicos com problemas como esses. Por que é tão difícil para os autores do TypeScript implementar um sinalizador de configuração simples?

Não acho que seja porque os desenvolvedores sejam preguiçosos ou porque não estejam dispostos a ajudar. Não acho que ninguém aqui seja uma pessoa má, exceto eu.

É esse conflito, esse debate, que se arrasta há anos sobre o que parece ser a definição da propriedade "rootDir". E o que fazer sobre este assunto.

As pessoas são lançadas neste debate porque acreditam que estão certas. Sim, "rootDir" serve como diretório base para o código-fonte. Sim, o erro é válido.

No entanto, o problema subjacente ainda persiste. Meu conjunto de ferramentas compila o código perfeitamente, mas meu IDE exibe esse erro na tela. É uma perversão. Eu quero que essas linhas vermelhas desapareçam. Meus arquivos não contêm erros. E se o fizerem, devo focar neles, em vez de me distrair com esses não-problemas.

Tudo que eu quero é suprimir essa mensagem de erro. Acho que é isso que a maioria de nós deseja. Não sei se há outros casos aqui e talvez haja pessoas que gostariam de falar sobre isso.

Podemos trabalhar juntos e resolver este problema? Eu ficaria muito feliz em ver essas linhas vermelhas sumirem ...

@nullquery Se tsc funcionar, mas seu IDE estiver mostrando seus rabiscos vermelhos, isso significa que seu IDE não está usando a mesma versão do compilador ou configuração de tsc .

@nullquery arquiva um bug que mostra como reproduzir o problema e nós o consertaremos ou informaremos o que há de errado com a configuração do seu projeto

Seguindo a partir da solução alternativa @sebelga , aqui está uma variação que é adequada para entrar em seus scripts npm

tsc --module commonjs --target ESNext --outDir ./edition-esnext --project tsconfig.json && test -d edition-esnext/source && ( mv edition-esnext/source edition-temp && rm -Rf edition-esnext && mv edition-temp edition-esnext ) || true

Exemplo de uso aqui.

O limite o aplicará para você automaticamente.

A solução são as referências do projeto .

Para usar isso, edite seu arquivo "tsconfig.json" e adicione-o ao final do arquivo (fora de "compilerOptions"):

"references": [
    { "path": "../common" }
]

Isso permitirá que você faça referência a arquivos na pasta "../common/" (e em todas as subpastas).


Minha confusão anterior era decorrente do fato de que o IntelliJ e minha tarefa gulp-typescript não contaminada estavam me dando resultados diferentes, apesar de usar o mesmo arquivo "tsconfig.json".

Acontece que, por algum motivo, "gulp-typescript" está tentando uma abordagem de melhor esforço para a compilação.

Um erro no TypeScript (como let z: number = '' ) será sinalizado no IntelliJ, mas "gulp-typescript" o compila perfeitamente.
Apenas erros de sintaxe de JavaScript (como let 1z = '' ) são sinalizados por "gulp-typescript".

Portanto, se você for um usuário "gulp-typescript", poderá enfrentar esse problema dependendo da sua versão do "gulp-typescript" e da sua configuração. (Estou usando a versão mais recente no momento em que escrevo, mas presumo que alguém do futuro possa estar lendo isso. Espero que os tempos sejam melhores para você.)


Eu sei que o uso de Referências de Projeto está enterrado em algum lugar nesta avalanche de respostas, mas teria sido melhor se isso fosse melhor documentado.

Os três principais resultados para "TS6059" no Google levam a problemas no GitHub. Teria ficado muito mais claro para mim se houvesse uma página documentando esses erros comuns e suas soluções.

@MicahZoltu Isso é algo que pode ser resolvido? Devo fazer um novo problema ou isso é algo que seria mais rápido se fosse discutido internamente entre os contribuidores principais?

(FWIW, não faço parte da equipe TypeScript)

Geralmente, eu não recomendo usar path s, a menos que seja absolutamente necessário. Acredito que seu propósito seja permitir a compatibilidade com projetos JS legados com estruturas de dependência estranhas, mas não acredito que seja para ser usado em novos projetos, e se você precisar dele, considere a possibilidade de migrar para longe dele quando você tem a oportunidade. Não o uso pessoalmente, então não posso realmente ajudar com os problemas que você possa ter com ele, mas tenho visto muitas pessoas lutando com ele e a solução geralmente é "pare de usá-lo".

Quanto ao gulp-typescript, parece que talvez a versão do TSC usada pelo gulp-typescript seja diferente da versão do TSC usada pelo IntelliJ. Quando você vê sintomas como os que descreveu, geralmente é esse o problema (o outro é que eles não estão usando o mesmo tsconfig.json ).

A versão usada por "gulp-typescript" deve ser idêntica; ambas as versões são derivadas de node_modules . Eu tentei várias maneiras de detectar erros e modificar as configurações relacionadas a eles (incluindo mexer com os vários "repórteres" fornecidos por "gulp-typescript" e tentar substituir as configurações para emitir mais erros. Nada parece funcionar.

Mas está bem. Contanto que o IntelliJ me forneça erros, fico feliz em aceitar que a tarefa Gulp os ignorará.


Não sou fã de reformular meu método em favor do método preferido da semana. A estrutura do projeto que tenho faz sentido para mim. Ele mantém tudo contido, mas me dá a flexibilidade de dividir as coisas em vários componentes.

Eu não acredito em "permitir compatibilidade por motivos de legado" e especialmente quando se trata de referências de projeto. _Deve_ ser possível fazer referência a arquivos fora de rootDir ou você simplesmente não terá a liberdade de definir a estrutura do projeto de uma forma que faça sentido para você e sua equipe.


Quando comecei a trabalhar com o TypeScript, tive vários problemas. Entre eles:

  • Para incluir arquivos JavaScript, a solução ideal parecia ser a AMD na época. O site parecia oficial e havia muitos exemplos online de uso da AMD em produção. Mas, aparentemente, o Webpack era a grande novidade e, portanto, alguns projetos simplesmente não funcionavam em um ambiente AMD. Lição aprendida: nem todo mundo vai adotar o novo método, então você está sempre ferrado.

  • O caminho do TypeScript para o JavaScript minimizado finalizado (com mapeamentos de origem) não estava claro para mim. Vários métodos diferentes estavam disponíveis na época, mas nenhum deles parecia funcionar nativamente com arquivos "tsconfig.json" e / ou meu IDE na época. Lição aprendida: se você quer que algo seja bem feito, você precisa fazer você mesmo; não confie em outras pessoas para fazer o trabalho por você, não importa o quão bem-intencionadas elas sejam, ninguém é perfeito e ninguém pode prever _seu_ espaço de trabalho.

  • Havia uma coisa personalizada que eu queria: uma maneira de converter o conteúdo de arquivos HTML em um dicionário JavaScript para inclusão. Este deveria ter sido meu único obstáculo, mas no final, acabou sendo um dos scripts mais fáceis de escrever.

Acabei tendo que desenvolver meu próprio Gulpfile para lidar com tudo. Ele faz o seguinte:

  • Copia os arquivos JavaScript minimizados para distribuição da pasta node_modules para meu webroot. Parece simples, mas quase todas as bibliotecas JavaScript que tentei incluir tinham um local diferente onde armazenavam seus arquivos JavaScript minimizados. Não havia configuração, nenhum caminho claro para os arquivos. Acabei tendo que escrever scripts separados para cada biblioteca JavaScript que queria incluir. Funciona, assumindo que o local não muda nas versões futuras, mas se mudar, sempre posso alterar o script de cópia.

  • Compila o TypeScript de acordo com o arquivo local "tsconfig.json" que gera arquivos separados em um diretório de saída (usando outDir ) para que eu possa ter certeza de que o TypeScript é compilado da mesma forma em meu IDE como será no Gulp (hahahahaha!), em seguida, usa o plug-in "rollup" para compactar esses arquivos em um único arquivo JavaScript e, em seguida, executa UglifyJS para reduzir esse arquivo, tudo isso enquanto mantém um mapeamento de origem que mapeia de volta para o arquivo TypeScript original.

  • (Tarefa personalizada) Gera um arquivo JavaScript contendo um dicionário chamado html_templates para cada arquivo HTML na raiz de origem do TypeScript e o coloca em minha pasta webroot como um arquivo JavaScript reduzido.

Pode haver maneiras mais elegantes por aí, mas depois de pular de um projeto de código aberto para o próximo, eu já estava farto de fazer malabarismos com as soluções que cada um deles estava oferecendo.

A abordagem que escolhi funciona, é simples de entender (especialmente agora que entendo que "gulp-typescript" faz algo diferente) e provavelmente continuarei usando isso nos próximos anos.

A melhor solução é aquela que você mesmo entende. Embora isso não ajude ninguém que tente me ajudar (o que eu aprecio muito! A ajuda, quero dizer, não a confusão), posso falar por experiência própria que sempre haverá algo errado com _qualquer_ solução, então é melhor ficar com algo você possui a si mesmo do que algo que é projetado, desenvolvido e produzido por uma equipe multicultural de várias crenças, orientações sexuais e identidades de gênero .


tl; dr, por favor, não quebre as referências do projeto. Preciso disso para que minhas ferramentas funcionem. obrigada

Desisti de definir a configuração do TS multiprojeto proerly e apenas faço tsc -w em cada projeto e npm link , e então você pode simplesmente ignorar todas as complexidades do tsconfig multiprojeto e apenas consultar outros projeto como se fossem dependências simples do node.js em node_modules .

Mas hoje em um projeto eu mudei o alvo de es5 para es6 e ele não compilará mais porque File '.../lib.ts' is not under 'rootDir' .

Estrutura do arquivo:

/app
 - tsconfig.json // rootDir = "."
 - app.ts (

/app/node_modules/lib
 - tsconfig.json // rootDir = "."
 - lib.ts
 - lib.js
 - lib.d.ts

Por que tsc em /app preocupa com o arquivo /app/node_modules/lib/lib.ts ? Ele não deve usar esse arquivo. Foram compilados /app/node_modules/lib/lib.js e /app/node_modules/lib/lib.d.ts .

Se /app/node_modules/lib/lib.ts excluído - surpresa - compila perfeitamente.

@alexeypetrushin você pode dar uma olhada em alguns dos meus projetos. Parece estar funcionando bem. por exemplo:

import * as pkg from '../package.json';

NÃO. E não há como desativar esse erro que eu encontro.

@SephReed : Gastei 200 pontos de representação no StackOverflow e alguém contribuiu com esta solução muito simples para importar ../package.json . Tudo que você precisa fazer é colocar um arquivo typings.d.ts no mesmo diretório que package.json , com este conteúdo:

declare module '*.json';

Não tenho ideia de como isso funciona, mas, honestamente, não me importo. Nesse estágio, o TS estava se bifurcando para si mesmo, não para mim.

Estou surpreso que seja um debate tão acalorado. Mas eu entendo o raciocínio. Para mim, é claro que tenho a pasta de origem, mas também tenho scripts de criação fora dessa pasta que não devem ser compilados, mas definitivamente incluem suporte a tipos, porque vamos ser honestos, seu melhor IntelliSense é o TypeScript.

repo/
⊢ config/  << provide TS support, but don't build this directory
  ⨽ webpack.config.ts 
⊢ scripts/  << provide TS support, but don't build this directory
  ⨽ release.ts
⊢ src/        << build this directory
  ⨽ example.ts
⨽ tsconfig.json

Portanto, eu uso "rootDir": "src" para ter certeza de que os arquivos são direcionados para dist e não dist/src . Mas é claro que o TypeScript gosta de reclamar dessa configuração, mas, como uso o Webpack, não há erro para mim.

Eu finalmente entendi o que este sinalizador significa exatamente, sem vários comentários que não tornam isso mais claro. Apenas comemore com isso.

As opções que definem pastas e arquivos para tsc para levar em consideração em conformidade: "arquivos", "incluir", "excluir".

Então, para que você usa "rootDir"?
rootDir é a raiz da estrutura de diretório (hierarquia) para seus arquivos de origem, que tsc usa para emitir a mesma estrutura de diretório a partir do diretório tsconfig.json ou "outDir" se for especificado. Portanto, este não é o caminho que o tsc usa como caminho base para "outDir". "outDir" é apenas a raiz que o tsc emite arquivos de saída.
Por exemplo, digamos que seu projeto java tenha esta estrutura de diretório.

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

Quando você define "include" e "rootDir" conforme abaixo, tsc irá gerar a saída como:

"include": "src/main/resources/static/ts" *
"rootDir": "." *

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.js *
          test.ts

Quando você também define "outDir" como abaixo, tsc irá gerar a saída como:

"include": "src/main/resources/static/ts"
"rootDir": "."
"outDir": "build" *

- build
  - src
    - main
      - resources
        - static
          - ts
            test.js *
- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

Provavelmente você queria ter isso definindo a opção "rootDir" e alterando a opção "outDir" conforme abaixo.

"include": "src/main/resources/static/ts"
"rootDir": "src/main/resources/static/ts" *
"outDir": "src/main/resources/static/js" *

- src
  - main
    - java
    - resources
      - static
        - js
          test.js *
        - ts
          test.ts

Portanto, quando você define a opção "rootDir" que não cobre os escopos dos arquivos, exceto a opção "excluir", tsc falha na construção porque não faz sentido com o propósito da opção "rootDir".

Sim, é uma prática de nomenclatura completamente ruim. Deveria ser apenas "rootOfStructureOfInputs" ou algo assim. E também, "outDir" deveria ser apenas "rootOfOutputs".

O que você vê no SS não é um problema do WebStorm - vem do TS DevServer.
A segunda importação recomendada é uma porcaria. Ele pega na pasta de origem de "comunicação". Eu não sei quem diabos deveria querer isso. Compilar um arquivo com essa importação produz uma série de problemas.

Eu também tentei:

"exclude": ["lib", "node_modules",
        "..", "../..", "../../..", "../../../..", "../../../../..", "../../../../../.."
    ]

Também não resolveu o problema

Bildschirmfoto 2020-07-22 um 10 08 28

@mhegazy Você rotulou esse problema como "Funcionando conforme pretendido", mas isso não é verdade. Como você pode ver em minha imagem, tsc-server fornece arquivos fora de meu rootDir (neste caso mobiservice / src) como sugestão de importação. Para mim, isso parece um bug ...

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

MartynasZilinskas picture MartynasZilinskas  ·  3Comentários

CyrusNajmabadi picture CyrusNajmabadi  ·  3Comentários

seanzer picture seanzer  ·  3Comentários

siddjain picture siddjain  ·  3Comentários

DanielRosenwasser picture DanielRosenwasser  ·  3Comentários