Typescript: tsc no debería importarle y fallar con archivos ts fuera de rootDir

Creado en 21 jul. 2016  ·  87Comentarios  ·  Fuente: microsoft/TypeScript

TypeScript: 2.0.0

Tengo una carpeta fixtures que contiene .ts archivos. En mi tsconfig.json configuré rootDir en src que contiene todo mi código fuente (incluida la prueba).

Los archivos de accesorios están ahí para casos de prueba. tsc no debería quejarse de su existencia y fallar la compilación.

Working as Intended

Comentario más útil

Bleh, ¿esto realmente funciona como se esperaba? Me encontré con esto, le dije a mecanografiado que mi fuente estaba en una carpeta en particular (a través de rootDir ) y luego procedí a _ ignorar por completo lo que le dije_ porque tenía un solo archivo con un .ts extensión

Esto realmente se siente como un error, si le digo al compilador dónde está mi fuente a través de rootDir , no debería ignorar por completo esa configuración y cambiar la estructura de mi carpeta de salida porque piensa que tal vez hice algo mal. Simplemente debería ignorar cualquier archivo que no esté en rootDir . Alternativamente, debería fallar, ¡no continuar emitiendo una salida que no se alinee con la estructura de carpeta de salida deseada en absoluto!


Para cualquiera que venga después de mí, lo siguiente hará lo que _en realidad_ quiere:

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

Todos 87 comentarios

Para desplazarme, agrego "excluir" de nuevo a mi tsconfig.json

rootDir se usa para construir la estructura de la carpeta de salida. todos los archivos deben estar en rootDir para que el compilador sepa dónde escribir la salida. sin esta restricción, si hay archivos que no están bajo rootDir, el compilador tiene dos opciones: 1. o serán emitidos en un lugar totalmente inesperado, o 2. no emitidos en absoluto. Yo diría que un mensaje de error es mucho mejor que un fallo silencioso.

@mhegazy Gracias por la aclaración. Por el nombre rootDir lo tomé como el directorio raíz del código fuente, muy parecido a baseURL para el navegador. No sabía que es solo para la estructura de la carpeta de salida.

Aquí está mi 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"
    ]
}

Mi estructura de carpetas se ve así:

  • proyecto

    • construir

    • node_modules (enlace simbólico a ../node_modules)

    • módulos_nodo

    • src

Quiero que mis archivos .ts en la carpeta src se compilen y se generen con las mismas estructuras de carpetas en la carpeta de compilación. Hago esto para poder establecer la raíz de mi documento en la carpeta de compilación y mantener mi src fuera de la raíz del documento. Recibo mensajes de error sobre archivos .ts en la carpeta node_modules, los mismos mensajes de error que OP. Tenga en cuenta que he excluido node_modules. ¿Por qué tsc se queja de eso?

@HillTravis, su problema parece ser el mismo que https://github.com/Microsoft/TypeScript/issues/9552.

@mhegazy No estoy seguro de que sea lo mismo. Sí, mi estructura incluye un enlace simbólico, pero se debe ignorar cualquier lugar donde exista ese enlace simbólico.

En # 9552, no hay una carpeta src, lo que significa que la carpeta node_modules existe en la ruta que se está construyendo. En mi escenario, el directorio raíz que debería buscar tsc es src, que no contiene node_modules. Por lo tanto, no debería mirar esa carpeta en absoluto. Además de eso, tengo la carpeta node_modules explícitamente excluida a través de mi tsconfig.json. Por tanto, debería ignorarse doblemente. También tengo la carpeta build excluida, y eso debería cubrir el enlace simbólico a node_modules dentro de ella.

Además, en el n. ° 9552, no se mencionan los mensajes de error ni la compilación fallida.

También debo mencionar que estoy usando TypeScript 1.8.10.

Específicamente, los mensajes de error dicen:

error TS6059: El archivo '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.module.ts' no está en 'rootDir' '/ Users / thill / Projects / nrc / client / src '. Se espera que 'rootDir' contenga todos los archivos fuente.

error TS6059: El archivo '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.ts' no está en 'rootDir' '/ Users / thill / Projects / nrc / cliente / src '. Se espera que 'rootDir' contenga todos los archivos fuente.

error TS6059: El archivo '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/timepicker-event-interface.ts' no está en 'rootDir' '/ Users / thill / Projects / nrc / client / src '. Se espera que 'rootDir' contenga todos los archivos fuente.

@HillTravis , puedes confiar en mí en este caso :) es nuestro manejo inconsistente de los enlaces simbólicos lo que desorienta al compilador. seguimos los enlaces simbólicos solo para la resolución del módulo de nodo, luego usamos ese nombre como el nombre del archivo; luego, realizamos una verificación para asegurarnos de que todos los archivos estén en el directorio de origen utilizando la ruta real, en lugar de la ruta especificada por el usuario. y eso es lo que genera el error.

Como prueba, intenté eliminar el enlace simbólico. En realidad, eliminé toda la carpeta build . Luego ejecuté tsc nuevamente y aún vi el error.

Durante más pruebas, intenté comentar la importación en código y los usos de ese módulo de nodo en particular (ng2-datetime) y el error desapareció. Entonces, solo cuando intento importar ese módulo de nodo veo el error, independientemente del enlace simbólico.

Si observa la fuente de ese paquete en GitHub, verá que el archivo package.json tiene el parámetro "principal" establecido en "ng2-datetime.js", aunque el autor también publicó el archivo .ts con el mismo nombre. Esto parece estar causando el problema. Si creo archivos .d.ts y elimino los archivos .ts, el problema desaparece. Se compiló sin problemas incluso después de volver a agregar el enlace simbólico.

Entonces, con todo respeto, no veo cómo este problema podría estar relacionado específicamente con el enlace simbólico. En general, parece causar problemas cuando el autor incluye los archivos .ts en el paquete.

¿Sabes si hay alguna solución para esto? El OP anterior dijo que lo solucionó agregando "exclude" nuevamente al tsconfig.json. Ya tengo el directorio excluido, pero todavía estoy intentando compilarlo.

¿Sabes si hay alguna solución para esto? El OP anterior dijo que lo solucionó agregando "exclude" nuevamente al tsconfig.json. Ya tengo el directorio excluido, pero todavía estoy intentando compilarlo.

Esto puede estar relacionado con otro, pero no puedo encontrarlo en este momento. Al buscar un tipo, tsc siempre intenta buscarlo desde node_modules , mientras no esté allí (relacionado con typings ).

"A tsc no debería importarle y fallar con archivos ts fuera de rootDir" Estoy de acuerdo.

No puedo entender por qué mecanografiado estaría mirando archivos JS fuera de rootDir, ya que ahí es donde debería estar toda la fuente.
El mensaje de error dice "se espera que 'rootDir' contenga todos los archivos fuente", entonces no se debe esperar ni suponer que cualquier cosa fuera de ese directorio sea un archivo fuente, en lo que respecta a TS!

Si se trata de "Trabajar según lo previsto", ¿cuál es exactamente la intención o la motivación de este comportamiento? ¿Existe algún caso en el que TS quiera compilar archivos fuente ubicados fuera de rootDir?

Por otro lado, agregar una sección "incluir" en tsconfig resuelve el problema. Cuando se le proporcionan archivos o directorios para incluir, TS no busca otros archivos fuera de ese.

con mecanografiado 1.8.10

Tenía una carpeta node_modules en mi homedir ~/node_modules . Ejecutar tsc desde mi directorio de proyecto ~/projects/myProject/ provocó que mecanografiado se quejara de los siguientes archivos

../../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.

muy confuso, aunque no estoy seguro de por qué tenía una carpeta de módulos de nodo en mi directorio de inicio para empezar.

@iwllyu puede verificar su proyecto en [email protected] y presentar un nuevo problema si aún tiene problemas.

Todavía tengo el problema con 2.1.4 aunque se queja de un conjunto diferente de archivos

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'.

Crearé un proyecto para aislar el caso de prueba.

Bueno, lo intenté con un proyecto nuevo y no estaba sucediendo. Dado que este es un proyecto anterior y ya lo arreglé eliminando la carpeta adicional node_modules, no voy a perder más tiempo tratando de recrearlo. ¡Gracias por la ayuda!

Sobre este caso. Si todo lo que importa son tipos (como si realmente estuviera navegando en esta onda "front-typecript, back-typecript") desde afuera, ¿tal vez tsc pueda distinguir lo que estoy haciendo?
Estoy compartiendo solo tipos de mis entidades desde el backend hasta mi aplicación frontend. Salida, por supuesto, sin tipos e importaciones de esas clases (porque se usan solo para tiempo de compilación e intellisense).

Tenía esto también.
Mecanografiado es demasiado restrictivo para nuestro equipo, considerando el flujo ahora.

chicos, ¿alguna resolución sobre esto ahora? utilizando tipos de código de cliente dentro del código de backend y de otro modo.

cual es la mejor opcion? copiar y pegar allí y allá y modificar si cambio los tipos?

hacer un directorio raíz para 2 proyectos no es una opción, ya que el backend tsconfig.json tendrá información sobre jsx y se compilará en commonjs cuando pueda usar es2015

¿ baseUrl funciona para usted?

@unional no cambiará baseUrl romperá todas las importaciones de node_modules, lo que requiere escribir no

import * as request from "superagent";

pero

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

?

Bleh, ¿esto realmente funciona como se esperaba? Me encontré con esto, le dije a mecanografiado que mi fuente estaba en una carpeta en particular (a través de rootDir ) y luego procedí a _ ignorar por completo lo que le dije_ porque tenía un solo archivo con un .ts extensión

Esto realmente se siente como un error, si le digo al compilador dónde está mi fuente a través de rootDir , no debería ignorar por completo esa configuración y cambiar la estructura de mi carpeta de salida porque piensa que tal vez hice algo mal. Simplemente debería ignorar cualquier archivo que no esté en rootDir . Alternativamente, debería fallar, ¡no continuar emitiendo una salida que no se alinee con la estructura de carpeta de salida deseada en absoluto!


Para cualquiera que venga después de mí, lo siguiente hará lo que _en realidad_ quiere:

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

Le dije a mecanografiado que mi fuente estaba en una carpeta en particular (a través de rootDir)

¡Esto no es lo que significa rootDir ! rootDir significa "Use esta carpeta como la base relativa para calcular las rutas en outDir ". Qué archivos forman parte de su compilación es una pregunta separada que es respondida por files y / o include / exclude

Incluso si acepto eso, el comportamiento actual sigue siendo un error en mi opinión. Si tengo archivos TS fuera del directorio especificado, rootDir _no_ será la base para calcular las rutas en outDir , lo que significa que la configuración que especifiqué se ignorará por completo.

Creo que fallar seriamente sería mucho mejor porque el compilador cree efectivamente que he dado una configuración no válida. Ignorar la configuración cuando no es válida (IMO) no es la forma correcta de manejar esta clase de falla.

Ejemplo de mensaje de error que sería mucho más claro (junto con una falla grave):

TSC encontró archivos mecanografiados fuera de rootDir y, por lo tanto, no puede continuar con la compilación. Cambie rootDir para incluir todos los archivos mecanografiados, o excluya archivos fuera de rootDir, o incluya solo archivos dentro de rootDir.

Nota: Una gran parte de la razón por la que el comportamiento actual de rootDir se siente muy mal es precisamente porque no tiene sentido tener archivos fuera de rootDir. Cuando uno se pregunta a sí mismo (o al compilador) qué significa compilar archivos fuera de rootDir la única respuesta es "no tiene sentido". Por lo tanto, se llega a la conclusión natural de que rootDir también especifica sourceDir.

El mal está en el nombramiento. Realmente significa relativePathBaseDir o algo así.

También he notado que include normalmente significa "mira aquí también", pero en este caso significa "solo mira aquí".
Sería sensato que tuviera otro nombre y fuera obligatorio.

En mi opinión, este comentario debe tenerse especialmente en cuenta para confirmar que se trata de un error y debe volver a abrirse como tal:

Nota: Una gran parte de la razón por la que el comportamiento actual de rootDir se siente muy mal es precisamente porque no tiene sentido tener archivos fuera de rootDir. Cuando uno se pregunta a sí mismo (o al compilador) qué significa compilar archivos fuera de rootDir la única respuesta es "no tiene sentido".

De hecho, no tiene sentido . "Los archivos de origen fuera de rootDir " simplemente no son archivos de origen , sin importar su extensión o contenido. El compilador nunca los compilará. Entonces, ¿por qué se queja de su existencia? ¿Está celoso de que haya archivos que no están bajo su mandato?

+100 por ser un error (realmente desagradable). Considere la siguiente estructura de directorio:

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

Me gustaría que tsc compile solo src , porque ejecuto pruebas con ts-node . Tener rootDir: 'src' provocará un error de compilación actualmente. Si marca las pruebas y otras cosas que solo tiene la intención de ejecutar con ts-node (¿o incluso compilar por separado tal vez?) Como "excluidas", entonces comienzan a suceder cosas malas (por ejemplo, el resaltado de vscode se rompe en las pruebas )

De hecho, ninguna combinación de rootDir , excluded y todas las demás opciones satisface todos los requisitos (excluya las pruebas de la compilación mientras pueda ejecutarlas y trabajar con ellas).

Y realmente no creo que mi caso de uso sea único, por lo que vale la pena reconsiderar la etiqueta "trabajar según lo previsto" al menos desde el punto de vista de UX.

La configuración src / test / out fue un escenario clave abordado por las referencias del proyecto

Encontré este problema porque estaba buscando en Google por qué mecanografiado intentaba compilar mi archivo webpack.config.js después de configurar rootDir .

Le dije a mecanografiado que mi fuente estaba en una carpeta en particular (a través de rootDir)

¡Esto no es lo que significa rootDir! rootDir significa "Use esta carpeta como la base relativa para calcular las rutas en outDir". Qué archivos son parte de su compilación es una pregunta separada que es respondida por archivos y / o incluir / excluir

¡Esta es la respuesta! Los documentos de rootDir dicen

Especifica el directorio raíz de los archivos de entrada.

Lo que interpreté como "archivos de _fuente_ de entrada". Recomiendo que el comentario de @RyanCavanaugh reemplace la explicación actual para esta opción.

Vincular aquí: https://github.com/Microsoft/TypeScript/issues/11299 es un duplicado de este problema. (Solución: use incluir / excluir para especificar archivos a compilar, rootDir NO especifica qué archivos compilar).

@mhegazy ¿

También me enfrento a este problema y no he podido resolverlo.

La compilación tsc hace que el árbol salga de mi directorio incluido y lo lleve a las carpetas principales, lo que provoca errores de tipo duplicado.

Tengo una estructura de carpetas anidadas que se ve así:

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

Ahora, cuando intento ejecutar tsc desde el directorio de ejemplo, aparece el siguiente error:

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 puede ver por el error, tsc está recorriendo el árbol hacia arriba y fuera de la carpeta de ejemplo, ¡y mirando en la carpeta node_modules del directorio principal! Lo que se siente aún peor es que he intentado ignorar explícitamente el directorio principal node_modules con poco efecto.

Aquí está el tsconfig del directorio de ejemplo:

{
  "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"
  ]
}

¿Cómo puedo solucionar este problema? Nada de lo anterior parece funcionar para mí.

@lexwebb Tuve el mismo problema, verifica en tus archivos yarn.lock que @types/react tengan las mismas versiones.
Consulte https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes.

Aterricé aquí porque mi carpeta de activos contiene un archivo de video "MPEG Transport Stream" con la extensión .ts por lo que tsc se bloqueó incluso si la carpeta no estaba en mi ruta rootDir 😄

Lo arreglé agregando la carpeta de activos en las rutas exclude pero fue un comportamiento perturbador 🤔

Entonces resulta que tuve una versión ligeramente diferente de react tanto en el paquete padre como en el hijo json. Hacer coincidir las versiones eliminó exactamente el problema. Sigue siendo un problema que no pueda excluir la verificación de tipos de formularios de directorios principales.

Supongo que esto nunca se solucionará. Me encontré con el mismo problema. Cómo esto "funciona según lo previsto" está más allá de mi comprensión. Supongo que la intención era hacer que el compilador se ejecutara de una manera absurda.

Desde mi propia experiencia personal, la razón por la que una compilación mecanografiada se sale de tu árbol rootDir e intenta compilar cosas que no esperas es el hecho de que has (deliberadamente o inadvertidamente) referenciado directa o indirectamente a algo en ese área desde dentro de su rootDir . Si lo hace, la compilación seguirá el árbol de referencia independientemente de si ha intentado o no excluir el área que contiene el archivo de referencia. A veces puede ser un PITA tratando de averiguar cómo / dónde lo ha hecho, pero invariablemente encuentro que es mi culpa, no la culpa de tsc . Simplemente está haciendo lo que le he dicho que haga.

Siempre que esto me golpea es por tipos. Importo una interfaz o algo que vive en un archivo que importa algo más que vive en un archivo que importa otra cosa ... hasta que finalmente termino importando algo que vive en un archivo fuera de mi rootDir y muy a menudo en algo que estoy tratando de excluir explícitamente en mi configuración.

Algunos de ustedes llegan a la raíz de su dolor. Ninguna cantidad de configuración lo sacará de allí, solo debe mantener un control estricto de su estructura de importación.

@kpturner Eso suena muy razonable, pero un proyecto de prueba básico sin importaciones de carpetas cruzadas producirá el comportamiento del que todos se quejan.

¿En serio? Que nunca he visto :)

Las carpetas excluidas siempre se excluyen en todos mis proyectos, excepto cuando se dan las circunstancias a las que aludo.

¿Hay ejemplos básicos en este hilo? Difícil de decir desde mi teléfono.

Disculpas, la exclusión no es parte de la situación 'básica' a la que me refiero. Solo estoy señalando que las importaciones no parecen ser una causa del comportamiento (aunque tendría más sentido si ese fuera el caso).

es decir, compilar algo como esto resultará en un error.

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

Pero si su tsconfig.json ve así, esperaría que el mecanografiado compile todo en el directorio src y todo en el directorio test . Si solo desea que transpile solo cosas en src y envíe al directorio out , entonces su tsconfig.json tendría que ser

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

Entonces arrojaría un error TS6059 porque tiene algunos archivos fuera de rootDir . Entonces tienes que excluir aquellos:

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

que, cuando se transpile, generará una carpeta llamada out con una subcarpeta de src contiene src.js . La carpeta test se ignora por completo. Esto es lo que esperaría que sucediera, ¿no?

Er, de hecho, mi ejemplo tsconfig debería haber incluido rootDir y outDir debajo de compilerOptions como muestra en su primer ejemplo. También tiene razón en que cuando excluye test , test y sus archivos quedan excluidos. Originalmente, pensé que estabas diciendo que un (o el) culpable del error TS6059 es un archivo en rootDir importa algo desde fuera de rootDir aunque creo que te he leído mal. Independientemente, estoy de acuerdo con otros aquí en la sorpresa de que los directorios fuera de rootDir deben excluirse explícitamente como usted describe.

No, estaba diciendo (anteriormente) que el árbol de referencia puede hacer que las cosas se transpilen en su lista excluida, algo diferente.

El error TS6059 es un poco desconcertante al principio, pero lo veo como TS tratando de ayudarme a evitar que cometa errores. Si me he tomado la molestia de definir un rootDir y luego plonk mecanografiado vuela fuera de ese rootDir, entonces TS está diciendo efectivamente "oi, has creado un mecanografiado al que no puedo acceder, ¿verdad?"

O respondo "no, no está bien, lo arruiné" y muevo los archivos a rootDir
O
Digo “sí, es correcto y lamento no haberte informado”, y luego lo agrego a la lista de archivos excluidos.

Esto es demasiado complicado. Tengo un monorepo y parece que no puedo encontrar una manera de compilar correctamente cada paquete por sí mismo, emitiendo la estructura de directorio correcta, mientras importo paquetes locales (desde el mismo monorepo) usando la opción paths .

O la estructura del directorio en el directorio de salida contiene carpetas principales no deseadas o tsc se queja de que los archivos están fuera del directorio raíz.

No puede ser tan complicado, ¿verdad?

Independientemente de las opciones en cualquier combinación que use, tsc parece no poder manejar un monorepo con paths haciendo referencia a paquetes locales en el mismo monorepo. Probé --build , --project , references , paths , extends , rootDir , rootDirs , include , exclude , baseUrl , outDir en todo tipo de combinaciones con diferentes valores y al final se queja de que los archivos no están dentro del rootDir o se estropea al emitir una estructura de directorio incorrecta dentro de outDir .

No describiría lo que tengo como un monorepo, pero tengo tres proyectos diferentes en el mismo repositorio, y puedo transpilar cada uno de forma independiente sin problemas o interferencias de los demás. Cada proyecto tiene su propio tsconfig

Después de bastante tiempo probando y retocando pude hacer que se ejecutara un references en combinación con paths y ya no se ahoga al usar rootDir .

rootDir se usa para construir la estructura de la carpeta de salida. todos los archivos deben estar en rootDir para que el compilador sepa dónde escribir la salida.

¿Qué pasa con los archivos que no requieren ninguna salida? Tener un archivo json fuera de la raíz:

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

Porque no puedo compilar la versión ES6:

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

Sin embargo, con la primera versión, estoy perdiendo la seguridad de los tipos.

@mhegazy Este problema se cerró hace 3 años. Sin embargo, parece que sigue siendo una fuente de confusión 3 años después.

¿Podría volver a visitar este estado "Funcionando según lo previsto"? Dada la reacción de la comunidad en este hilo, es bastante seguro decir que no se está comportando como la comunidad espera que se comporte . Ya sea un problema de documentación, cambiar el nombre de esa opción, cambiar su comportamiento o agregar una nueva opción, creo que en realidad hay un elemento de acción de su lado por determinar.

Puedo entender que tiene prioridades mucho más altas que esta, pero mantener este problema cerrado sin ninguna señal de que los comentarios brindados aquí alguna vez hayan sido valorados no transmite una muy buena imagen para que Typecript sea honesto.

@ngryman ¿Qué próximo paso tenemos? rootDir tiene una definición : esta es la raíz común de mis archivos fuente. Cuando un archivo no está en esa raíz común, por la definición misma de rootDir , eso es un error. Esa definición está documentada. No puedo hacer nada sobre el hecho de que la gente haya inventado sus propias definiciones para rootDir y luego se sorprenda.

Esto es como ir a Starbucks y decir que pedir un café con leche no debería resultar en una mezcla de espresso y leche al vapor. Es inaccesible porque estás discutiendo con una definición . Si quieres una bebida diferente, pide otra. Si Starbucks no ofrece el tipo de bebida que desea, sugiera cuál debería ser esa bebida y de qué debería estar hecha.

Como mencioné en https://github.com/microsoft/TypeScript/issues/9858#issuecomment -370653478, creo que la solución a este problema es simplemente una mejor mensajería de error. Cuando me encontré con él y finalmente encontré este problema de GitHub, mi mayor frustración vino de cuánto tiempo perdí tratando de resolver el problema, y ​​luego pensando que era un error del compilador, y luego creando un caso de reproducción, y luego encontrando un error duplicado que dice "funciona según lo previsto". Fallar rápidamente con un mensaje de error claro me habría ahorrado todo eso.

Si hay archivos de origen fuera de rootDir , significa que el proyecto de TypeScript está configurado incorrectamente. Darle al usuario un mensaje claro que indique esto junto con una guía sobre cómo solucionarlo, creo que resolvería el problema para mucha gente.

@RyanCavanaugh Gracias por su rápida respuesta.

Si voy a esta página: https://www.typescriptlang.org/docs/handbook/compiler-options.html. Leí la siguiente definición:

Especifica el directorio raíz de los archivos de entrada. Úselo solo para controlar la estructura del directorio de salida con --outDir.

Estoy literalmente entendiendo que " solo se usa para controlar la estructura del directorio de salida" y eso es todo. El " único uso " es importante aquí. ¿Cómo podría siquiera adivinar que no es lo único que el compilador está haciendo en realidad, sino que también emitirá errores si tengo archivos de Typecript fuera de ese directorio?

Quizás me esté perdiendo algo, pero si ese es el caso, estoy lejos de ser el único. Entonces, si tiene un producto, y una buena cantidad de sus usuarios no entienden su producto, solo hay 2 caminos a seguir: o considera que sus usuarios son estúpidos o no pudo comunicar algo con claridad. Espero que no te estés inclinando hacia el primero 😕

Para terminar con tu ejemplo de Starbuck, escribe "mezcla de expresso y leche al vapor" en la lista de ingredientes, así sé qué es un café con leche y no tengo que adivinar.

La implicación de un archivo fuera de rootDir sería que TS generaría un archivo fuera de outDir , lo que creo que es un comportamiento evidentemente malo.

El mensaje de error podría ser mejor: me encantaría una sugerencia o un PR para eso.

Los documentos siempre podrían ser mejores; de nuevo, me encantaría tener ideas concretas sobre cómo comunicar las cosas con mayor claridad.

Insinuar que llamo a la gente estúpida ya no es algo que me gustaría.

La implicación de un archivo fuera de rootDir sería que TS generaría un archivo fuera de outDir, lo que creo que es un comportamiento evidentemente malo.

Todavía no tengo muy claro por qué el compilador no simplemente "chroot" a rootDir y no considera archivos fuera de ese directorio. Como usuario, probablemente sin contexto sobre tsc internos e historial, este definitivamente no es un comportamiento predecible para mí.

Un ejemplo que puedo dar de mi cabeza es Jest, que ofrece la misma opción: https://jestjs.io/docs/en/configuration#rootdir -string. AFAIK Jest no considera archivos de prueba fuera de rootDir . Esperaría el mismo comportamiento aquí, por ejemplo.

Los documentos siempre podrían ser mejores; de nuevo, me encantaría tener ideas concretas sobre cómo comunicar las cosas con mayor claridad.

Me alegra que esté considerando realizar mejoras aquí. La sugerencia de @MicahZoltu podría ser interesante de explorar.

Por mi parte, puedo reafirmar que no creo que rootDir sea ​​predecible (de ahí la reacción de la gente), pero según tengo entendido, cambiar el comportamiento de esa opción no es algo a considerar. Entonces, como compromiso, una cosa que también podría proponer sería cambiar el nombre de rootDir a un nombre más significativo, outBaseDir podría ser un candidato. Pero probablemente haya un nombre mejor.

Insinuar que llamo a la gente estúpida ya no es algo que me gustaría.

No insinué nada y lamento si lo tomó de esa manera. Solo expuse un hecho muy simple: cuando los usuarios se quejan de algo que no entienden, efectivamente solo hay 2 caminos a seguir. Llegué a la conclusión de que espero que no se inclinara por el primero. El hecho de que se asocie con uno de estos caminos se le deja honestamente a usted.

Creo que he dicho lo que tenía que decir, especialmente al dar comentarios sinceros sobre cómo se manejó este hilo. Así que dejaré espacio para que otros propongan soluciones.

@ngryman Estoy de acuerdo en que la definición de rootDir y lo que realmente está haciendo no parecen coincidir. Cuando crea un nuevo proyecto ts (a través de tsc --init ), el comentario en tsconfig.json para rootDir es similar a lo que citó /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ . Si proporciono un directorio de archivos _input_, espero que los únicos que siquiera considerará compilar están en ese directorio, según la definición de entrada.

@RyanCavanaugh Puede haber tenido sentido informar de un error como este hace 4 años cuando el mecanografiado solo se usaba para compilarlo en javascript. ¡Por supuesto que no quiero archivos perdidos! Pero ahora, con la popularidad de la ejecución mecanografiada, como ts-node , parece que tsc me está poniendo un poco celoso.

Y la idea de que los archivos mecanografiados fuera de rootDir implican una configuración incorrecta del proyecto es simplemente incorrecta. No necesito que mis pruebas unitarias, que están escritas en mecanografiado, se compilen en javascript. ts-node es simplemente más rápido y puedo disfrutar de todos los beneficios del mecanografiado al escribir pruebas.

Estoy de acuerdo con @CodySchrank . Estoy de acuerdo con que TS tenga un error cuando algún archivo fuente dentro de rootDir hace referencia / importa un archivo fuera de él, eso es de esperar.

Sin embargo, no puedo entender que TypeScript mire por sí mismo a través de archivos no relacionados fuera de rootDir y cometa errores, mientras que esos son simplemente archivos de configuración para diferentes herramientas, como jest o lo que sea. Quiero decir, ¿cuál es el punto? Estas ni siquiera son partes de mi aplicación y no se mencionan / importan en ningún lugar directamente, y Dios mío, ¿por qué querría que se incluyan en la compilación resultante en primer lugar ...

Me pregunto cuáles serían las implicaciones de convertir este error en una advertencia. Habiendo hojeado brevemente el código, ciertamente parece posible, pero definitivamente no soy un experto en el proceso de compilación de tsc. Parece un medio feliz entre mantenernos notificados sobre un problema potencial y también permitirnos evitarlo si queremos.

La configuración src / test / out fue un escenario clave abordado por las referencias del proyecto

Esto requiere al menos una configuración de proyecto separada para cada carpeta raíz (https://www.typescriptlang.org/docs/handbook/project-references.html). Después de leer las instrucciones, me fui sin una buena comprensión de cómo implementar el patrón y siento que me están entregando un martillo neumático cuando lo que solicité fue un matamoscas.

Claro, mantener los módulos adjuntos como subproyectos separados dentro de mi carpeta de origen es más eficiente, pero no estoy compilando lodash aquí. Lo que quiero es incluir muchos archivos, como archivos de prueba y de referencia, en una carpeta de proyecto común para el análisis estático, y cuando llegue el momento de compilar, solo emita un directorio único para que lo use el mundo exterior. Esto parece bastante fácil de especificar y estoy luchando por ver por qué no solo es difícil para el usuario hacerlo, sino aparentemente _verboten_ desde la perspectiva de la especificación TS.

Lo que quiero enfatizar es que la única razón por la que esta función no está permitida se debe a que el compilador asume una intención corrupta por parte del desarrollador. Cuando el desarrollador establece "outDir" en ./src y el compilador encuentra un archivo TS en ./test , _podría_ asumir que este archivo no necesita ser emitido (asumiendo, por supuesto, que no se hace referencia a ella desde ningún archivo en "outDir").

Pero no es así. Se asume que el desarrollador _quiso_ emitir este archivo, y por incompetencia o malicia especificó un subdirectorio que no lo contiene. En otras palabras, el compilador tiene la oportunidad de hacer coincidir las instrucciones del desarrollador con un caso de uso común y razonable y, en cambio, las compara con algo absurdo y se niega a continuar.

Tal como está, ni siquiera veo cuál es el caso de uso legítimo de "outDir" . Supongo que es para admitir una estructura de proyecto donde tsconfig.json está en el nivel superior junto con otros archivos de configuración y metadatos, y el propietario quiere que la carpeta compilada represente solo la carpeta de origen que está anidada dentro de ella. (Solo asegúrese de que ninguno de esos metaarchivos termine con .ts : eso sería absurdo).

Me parece que el diseño de la especificación es antagónico al usuario. Se hizo una referencia a pedir una bebida en Starbucks y estar molesto cuando no era lo que esperaba, a pesar de que los ingredientes estaban enumerados en el menú. Esto es apto en la medida de lo posible, pero compararía esta función más con un puesto de perritos calientes que no vende perritos calientes.

Claro, los clientes irritados deberían haber retrocedido y haber visto el gran letrero proclamando audazmente que el puesto de perritos calientes no vende perritos calientes. Pero a medida que se acumula la confusión, los propietarios del puesto de perritos calientes podrían tener la oportunidad de reflexionar sobre cómo están comunicando las capacidades de su producto a los clientes.

Hmm, considerando esto más, me pregunto si hay una especie de invariante por parte del equipo central que subyace a este problema:

Todo el código fuente debe estar compilado. Si no está compilado, no es código fuente.

En la tierra de los usuarios, existe la necesidad de superar esto de alguna manera. No sé si lo hacemos ampliando la definición de código fuente a saber. TypeScript, o creando una segunda categoría (“código de apoyo”, “código de validación”, “código periférico” ...). Este sería un código que se espera que opere bajo las mismas definiciones de tipo que la fuente, y que debe validarse con éxito para que la fuente se considere correcta, pero que no forma parte de la funcionalidad real del programa con respecto a su interfaz.

Como consumidor de TypeScript, no aprecio las dificultades específicas de implementar tal categoría. Sin embargo, parece que encajaría perfectamente con "outDir" : cualquier cosa dentro de "outDir" es parte de la fuente, cualquier cosa fuera de ella pero dentro de la carpeta del proyecto es parte del código de soporte. Lo principal que hace que esto sea útil / necesario es la llegada de ts-node, lo que significa que puedo ejecutar este código de soporte como un paso separado, completamente independiente de la compilación; y por supuesto quiero poder aprovechar eso.

no incluye implícitamente ningún archivo de entrada proporcionado a la herramienta

Este problema es causado exactamente _porque_ el usuario está implícitamente tratando de compilar archivos fuera de rootDir . Básicamente le dijo al compilador, "compile sólo archivos en este directorio" y luego procedió a hacer referencia a archivos fuera de ese directorio. El compilador está confundido y no sabe cómo proceder.


/project/source/index.ts

import '../external.ts'

/project/tsconfig.json

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

En este ejemplo, le dice al compilador que "los archivos fuente están solo en el directorio 'fuente'". Luego, uno de esos archivos hace referencia a un archivo que _no_ está en el directorio de origen. TypeScript ahora tiene dos instrucciones en conflicto, una dice que solo compile archivos en el directorio fuente, la otra dice que compile archivos fuera del directorio fuente.

@MattiasMartens estás combinando implícitamente include y rootDir . Si tiene /src y /test , si include es src/* entonces no puede obtener errores sobre las cosas en /test menos que algo de src importó incorrectamente algo de test , ¡por lo que debería estar feliz!

No es hostil ni antagonista para el usuario proporcionar un mecanismo para escribir cómo se ve una importación incorrecta en su programa y emitir un error cuando ocurre una importación incorrecta. Nuevamente, creo que esto proviene de un malentendido sobre lo que significan las banderas: son principalmente verificaciones de cumplimiento opcionales para ayudarlo a validar que su programa está configurado correctamente.


¡De todas formas!

Dada la definición de rootDir , cuando TypeScript ve un archivo fuera del rootDir , tiene algunas opciones:

  • Emite un archivo por encima de outDir (¡asumiendo que esto sea posible!), Que contradice las instrucciones del usuario sobre la ubicación de salida.
  • Procese el archivo pero no lo emita, que sin otros pasos de compilación producirá un programa que no funcionará
  • Emitir un error porque el proyecto parece estar mal configurado

Me opongo firmemente a la noción de que emitir un programa que no funciona debería ser el predeterminado. Si la solicitud de función aquí es simplemente para tratar .ts archivos encontrados fuera de rootDir como .d.ts , eso es razonable, es solo una cosa separada de rootDir significa algo que no sea rootDir . ¿Cómo llamarías a una bandera así?

@MattiasMartens estás combinando implícitamente include y rootDir . Si tiene /src y /test , si include es src/* entonces no puede obtener errores sobre las cosas en /test menos que algo de src importó incorrectamente algo de test , ¡por lo que debería estar feliz!

Eso es cierto. Analicé con include y descubrí que funciona mejor de lo que pensaba para este caso, incluso con las herramientas de VSCode.

Todavía me gustaría tener un código validado en la compilación pero que no se emite en la compilación, que es algo que include no cubre. Pero esa es una solicitud separada que no necesita ser discutida aquí.

Creo que esto se debe a un malentendido sobre lo que significan las banderas: son principalmente verificaciones de cumplimiento adecuadas para ayudarlo a validar que su programa está configurado correctamente.

Estoy confundido por esto. ¿Considera rootDir un cheque de cumplimiento de suscripción? Afecta a lo que finalmente se emite, por lo que claramente no es _sólo_ un control de cumplimiento.

Algunas banderas, como target , cambian drásticamente lo que se emitirá; no son comprobaciones de cumplimiento, sino instrucciones del compilador. rootDir lee y se documenta como una instrucción del compilador.

Me opongo firmemente a la noción de que _emitir un programa que no funciona_ debería ser el predeterminado.

Por lo que he leído de este hilo hasta ahora, parece haber un amplio consenso de que una referencia de un archivo dentro de rootDir a un archivo fuera de rootDir _ debería ser un error_. El aspecto de la función que yo y otros hemos encontrado frustrante es que no se detiene allí, sino que de hecho arroja un error si encuentra archivos TS en la carpeta del proyecto fuera de rootDir si un archivo en rootDir importa o no.

Vale la pena repetirlo: configuro rootDir en la carpeta donde reside mi código fuente, el compilador nota otro código TS en el proyecto que no tiene rootDir , ¡y se detiene! Este comportamiento específico no me ayuda a comprender mi código. Es simplemente molesto.

Es cierto que desde la perspectiva de la definición de TypeScript de rootDir , como se detalla en este hilo, el comportamiento es perfectamente razonable, y todos los que han venido aquí para expresar su frustración al respecto están en un error. Pero no es razonable a partir de la definición convencional esperada de un directorio raíz. Les digo que en prácticamente cualquier contexto en el que proporcione un directorio raíz, le estoy diciendo al programa dónde comenzar a recorrer la estructura de archivos, sin preguntarle si es absolutamente seguro que no hay algo más en el sistema de archivos que yo también podría estar interesado en.

Las definiciones pueden estar equivocadas. Pueden cambiarse. Para la compatibilidad con versiones anteriores, no es necesario conservar las definiciones, solo la funcionalidad.

Si la solicitud de función aquí es simplemente para tratar .ts archivos encontrados fuera de rootDir como .d.ts

Yo ... no creo que quiera eso, prácticamente por las mismas razones por las que quiero que el compilador arroje un error cuando algo en rootDir importa código desde fuera. Creo que el contenido de un rootDir si proporciono uno debería encapsularse del código circundante.

Creo que la forma más sencilla de evitar el comportamiento que yo y otros no queremos es excluir implícitamente archivos fuera de rootDir si los archivos en rootDir no se refieren a ellos. Si los archivos en rootDir no se refieren a ellos, un error debe ser desechado, ya que es actualmente.

Cada párrafo parece reducirse a " rootDir debería cambiar el valor predeterminado de include ", lo que sería razonable sugerir si estuviéramos agregando esas banderas hoy al mismo tiempo, pero no es un cambio revolucionario que podríamos hacer en este momento. Aunque podría decirse que hacer todas las banderas de configuración interactúan con cada carga cognitiva otros más aumentos en lugar de lo disminuye.

Tal vez deberíamos emitir un error personalizado cuando include no está configurado explícitamente y un archivo incluido está fuera de rootDir .

El archivo "tests / foo.ts" está fuera de rootDir 'src'. ¿Olvidó establecer un patrón de "inclusión"?

Registrado # 33515

También he tenido problemas con esto en https://github.com/microsoft/TypeScript/issues/31757#event -2480427393

La interacción entre rootDir, include y exclude tiene un diseño tan extraño.

Siempre pensé que rootDir es la carpeta que el compilador comienza a recorrer e incluye carpetas adicionales (por ejemplo, carpetas de proveedores) a las que se puede hacer referencia desde rootDir.

La definición actual es extraña como el infierno y extremadamente poco intuitiva.

Irónicamente, lo que es confuso es que no interactúan: las configuraciones no se afectan en absoluto. include tiene el 100% de control de lo que hay en el programa y rootDir tiene el 100% de control del cálculo del diseño de outDir .

Solo para agregar otro ejemplo del problema, esta es la estructura de mi carpeta:

tsconfig.json
package.json
src/index.ts

Tengo en mi tsconfig:

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

Y en mi "index.ts" (carpeta src)

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

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

_Sé_ que, después de la compilación, el archivo "index.js" estará dentro de la carpeta "lib". Y sé que el package.json subirá 1 nivel.
No creo que Typescript deba conocer mejor que yo la estructura de mi carpeta y romper la compilación. Simplemente debería registrar una advertencia sobre algunos archivos fuera de la carpeta rootDir que no se incluyeron en la carpeta de salida.

@sebelga Probablemente consideraría que es un error: permitir .json desde fuera de rootDir estaría bien ya que TS no copia eso en la carpeta de salida

@sebelga Probablemente consideraría que es un error: permitir .json desde fuera de rootDir estaría bien ya que TS no lo copia en la carpeta de salida

Gracias, no es cierto ... Tenemos algunas reglas especiales para emitir archivos .json ... Si el archivo se va a emitir en la misma ubicación en sí mismo, entonces y solo entonces no se emitirá. En todos los casos se emite (por ejemplo, cuando se especifica --outDir, se emitirá en esa carpeta)

@RyanCavanaugh Tengo un caso de uso similar al de @sebelga donde quiero console.log sacar el número de versión de package.json en tiempo de ejecución.

Entonces mi solución fue cambiar mi "rootDir": "." , luego tengo esto incluye

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

Y como el archivo package.json está incluido en la carpeta lib (built), que contiene una subcarpeta "src", escribí un script bash que se ejecuta justo después de la compilación para limpiar las cosas.

#!/bin/bash

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

Funciona, pero me parece bastante extraño.

@sebelga ¿Tiene .ts archivos en la carpeta typings ? De lo contrario, sería legal establecer rootDir en src y omitir el script.

@sebelga En lugar de const { version } require('../../package.json') o import { version } from 'package.json') , ¿ha intentado hacer algo como esto:

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

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

TypeScript no se preocupará de que esté fuera de rootDir esta manera.

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

Si desea evitar codificar todos los ../.. , puede intentar esto:
https://github.com/sindresorhus/read-pkg-up

@RyanCavanaugh No puedo configurarlo en "src" como se mencionó anteriormente. Estoy importando "package.json" fuera de nuestro src ( import pkg from '../package.json'; ) y tsc no lo permite.

¡Gracias por compartir esto @dylang ! Voy a intentarlo.

Le dije a mecanografiado que mi fuente estaba en una carpeta en particular (a través de rootDir)

¡Esto no es lo que significa rootDir ! rootDir significa "Use esta carpeta como la base relativa para calcular las rutas en outDir ". _Qué archivos son parte de su compilación_ es una pregunta separada que es respondida por files y / o include / exclude

@RyanCavanaugh Pero eso es lo que debería significar rootDir , y de esto se trata este tema.

No soy tan bueno para mantener la compostura cuando veo problemas que han estado abiertos desde 2016 que probablemente podrían estar muy solucionados sin introducir nuevos problemas para los usuarios existentes al introducir una nueva "compilerOption" para que el compilador sepa que puede ignorar el error. en un caso de uso dado.

Por esto, me disculpo. No puedo evitarlo, porque se confía en mí para brindar un buen servicio, sin embargo, ocasionalmente me encuentro con temas problemáticos como estos. ¿Por qué es tan difícil para los autores de TypeScript implementar una bandera de configuración simple?

No creo que sea porque los desarrolladores sean perezosos o porque no estén dispuestos a ayudar. No creo que nadie aquí sea una mala persona, excepto yo.

Es este conflicto, este debate, que se ha prolongado durante años sobre lo que parece ser la definición de la propiedad "rootDir". Y qué hacer con este problema.

La gente se ve envuelta en este debate porque cree que tiene razón. Sí, "rootDir" sirve como directorio base para el código fuente. Sí, el error es válido.

Sin embargo, el problema subyacente aún persiste. Mis herramientas compilan el código perfectamente, pero mi IDE muestra este error en mi pantalla. Es una perversión. Quiero que esas líneas rojas desaparezcan. Mis archivos no tienen errores. Y si lo hacen, debería centrarme en ellos en lugar de distraerme con estos no-problemas.

Todo lo que quiero es suprimir este mensaje de error. Creo que eso es lo que la mayoría de nosotros queremos. No sé si hay otros casos aquí y tal vez haya gente a la que le gustaría hablar sobre eso.

¿Podemos trabajar juntos y resolver este problema? Me haría muy feliz ver desaparecer esas líneas rojas ...

@nullquery Si tsc funciona pero su IDE muestra sus garabatos rojos, significa que su IDE no está usando la misma versión o configuración del compilador que tsc .

@nullquery presenta un error que muestra cómo reproducir el problema y lo solucionaremos o le diremos qué está mal con la configuración de su proyecto

A continuación de la solución alternativa de @sebelga , aquí hay una variación que es adecuada para ir dentro de sus 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

Ejemplo de uso aquí.

Boundation lo aplicará automáticamente.

La solución son las referencias del proyecto .

Para usar esto, edite su archivo "tsconfig.json" y agréguelo al final del archivo (fuera de "compilerOptions"):

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

Esto le permitirá hacer referencia a archivos en la carpeta "../common/" (y todas las subcarpetas).


Mi confusión anterior se debía al hecho de que IntelliJ y mi tarea gulp-typescript no contaminada me estaban dando resultados diferentes a pesar de usar el mismo archivo "tsconfig.json".

Resulta que, por alguna razón, "gulp-typescript" está intentando un enfoque de compilación con el mejor esfuerzo.

Un error en TypeScript (como let z: number = '' ) se marcará en IntelliJ pero "gulp-typescript" lo compila muy bien.
Sólo los errores de sintaxis de JavaScript (como let 1z = '' ) están marcados por "gulp-typescript".

Por lo tanto, si es un usuario de "gulp-typescript", puede experimentar tal problema dependiendo de su versión de "gulp-typescript" y su configuración. (Estoy usando la última versión en el momento de escribir este artículo, pero supongo que alguien del futuro podría estar leyendo esto. Espero que los tiempos sean mejores para ti).


Sé que el uso de referencias de proyectos está enterrado en algún lugar de esta avalancha de respuestas, pero hubiera sido mejor si esto estuviera mejor documentado.

Los 3 primeros resultados para "TS6059" en Google conducen a problemas de GitHub. Habría sido mucho más claro para mí si hubiera una página que documentara estos errores comunes y sus soluciones.

@MicahZoltu ¿Es esto algo que se puede abordar? ¿Debo hacer un nuevo número, o es algo que iría más rápido si se discutiera internamente entre los principales contribuyentes?

(FWIW no soy parte del equipo de TypeScript)

Generalmente, recomiendo no usar path s a menos que sea absolutamente necesario. Creo que su propósito es permitir la compatibilidad con proyectos JS heredados con estructuras de dependencia extrañas, pero no creo que esté destinado a ser utilizado en ningún proyecto nuevo, y si lo necesita, puede considerar migrar lejos de él cuando tienes la oportunidad. No lo uso personalmente, así que no puedo ayudar con los problemas que pueda tener con él, pero he visto a mucha gente luchar con él y la solución suele ser "dejar de usarlo".

En cuanto a gulp-typescript, parece que quizás la versión de TSC que usa gulp-typescript es diferente de la versión de TSC que usa IntelliJ. Cuando ve síntomas como los que describe, ese suele ser el problema (el otro es que no están usando el mismo tsconfig.json ).

La versión utilizada por "gulp-typescript" debe ser idéntica; ambas versiones se derivan de node_modules . He intentado varias formas de detectar errores y modificar la configuración relacionada con ellos (incluido jugar con los diversos "reporteros" proporcionados por "gulp-typescript" e intentar anular la configuración para emitir más errores. Nada parece funcionar.

Aunque está bien. Siempre que IntelliJ me dé errores, estoy feliz de aceptar que la tarea Gulp los ignorará.


No soy fanático de revisar mi método en favor del método preferido de la semana. La estructura del proyecto que tengo tiene sentido para mí. Mantiene todo contenido, pero me da la flexibilidad de dividir las cosas en varios componentes.

No creo en "permitir la compatibilidad por razones heredadas", y especialmente cuando se trata de referencias de proyectos. _De_be ser posible hacer referencia a archivos fuera de rootDir o simplemente no tendrá la libertad de definir la estructura del proyecto de una manera que tenga sentido para usted y su equipo.


Cuando comencé a trabajar con TypeScript, encontré numerosos problemas. Entre ellos:

  • Para incluir archivos JavaScript, la solución de referencia parecía ser AMD en ese momento. El sitio web sonaba oficial y había muchos ejemplos en línea de AMD en uso de producción. Pero aparentemente, Webpack era la novedad y, por lo tanto, algunos proyectos simplemente no funcionaban en un entorno AMD. Lección aprendida: no todo el mundo va a adoptar el nuevo método, así que siempre estás jodido.

  • El camino desde TypeScript hasta el JavaScript minificado finalizado (con asignaciones de fuentes) no me quedó claro. Varios métodos diferentes estaban disponibles en ese momento, pero ninguno de ellos parecía funcionar de forma nativa con archivos "tsconfig.json" y / o mi IDE en ese momento. Lección aprendida: si quiere que algo se haga bien, debe hacerlo usted mismo; no confíe en otras personas para que hagan el trabajo por usted, no importa cuán bien intencionadas sean, nadie es perfecto y nadie puede predecir su espacio de trabajo.

  • Había una cosa personalizada que quería: una forma de convertir el contenido de los archivos HTML a un diccionario JavaScript para su inclusión. Este debería haber sido mi único obstáculo, pero al final, resultó ser uno de los scripts más fáciles de escribir.

Terminé teniendo que desarrollar mi propio Gulpfile para manejar todo. Hace lo siguiente:

  • Copia los archivos JavaScript minificados para su distribución desde la carpeta node_modules a mi webroot. Suena simple, pero casi todas las bibliotecas de JavaScript que intenté incluir tenían un lugar diferente donde almacenaban sus archivos JavaScript minificados. No había configuración, no había una ruta clara a los archivos. Terminé teniendo que escribir scripts separados para cada biblioteca de JavaScript que quería incluir. Funciona, asumiendo que la ubicación no cambia en versiones futuras, pero si lo hace, siempre puedo cambiar el script de copia.

  • Compila TypeScript de acuerdo con el archivo local "tsconfig.json" que genera archivos separados en un directorio de salida (usando outDir ), por lo que puedo estar seguro de que TypeScript se compila de la misma manera en mi IDE que en Gulp (¡jajajajaja!), luego usa el complemento "rollup" para comprimir esos archivos en un solo archivo JavaScript, luego ejecuta UglifyJS para minificar este archivo, todo mientras mantiene una asignación de origen que se asigna al archivo TypeScript original.

  • (Tarea personalizada) Genera un archivo JavaScript que contiene un diccionario llamado html_templates para cada archivo HTML en la raíz de origen de TypeScript y lo coloca en mi carpeta webroot como un archivo JavaScript minificado.

Puede que haya formas más elegantes, pero después de saltar de un proyecto de código abierto a otro, tuve suficiente de hacer malabares entre las soluciones que ofrecía cada uno de ellos.

El enfoque que he elegido funciona, es bastante simple de entender (especialmente ahora que entiendo que "gulp-typecript" hace algo diferente) y probablemente continuaré usando esto en los próximos años.

La mejor solución es aquella que se comprenda a sí mismo. Si bien esto no ayuda a nadie que intente ayudarme (¡lo cual agradezco mucho! Me refiero a la ayuda, no a la confusión), puedo decir por experiencia que siempre habrá algo mal con _cualquier_ solución, así que es mejor quedarse con algo. eres dueño de ti mismo que algo que está diseñado, desarrollado y producido por un equipo multicultural de diversas creencias, orientaciones sexuales e identidades de género .


tl; dr, por favor, no rompa las referencias del proyecto. Lo necesito para que mis herramientas funcionen. gracias

Dejé de configurar la configuración de TS multiproyecto correctamente y solo hago tsc -w en cada proyecto y npm link , y luego puede ignorar todas las complejidades de tsconfig multiproyecto y simplemente consultar otros proyecto como si fueran dependencias simples de node.js en node_modules .

Pero hoy en un proyecto cambié el objetivo de es5 a es6 y ya no se compilará porque File '.../lib.ts' is not under 'rootDir' .

Estructura de archivo:

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

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

¿Por qué tsc en /app preocupa por el archivo /app/node_modules/lib/lib.ts ? No debería usar ese archivo en absoluto. Hay compilados /app/node_modules/lib/lib.js y /app/node_modules/lib/lib.d.ts .

Si /app/node_modules/lib/lib.ts eliminado, sorpresa, se compila bien.

@alexeypetrushin puedes echar un vistazo a algunos de mis proyectos. Parece estar funcionando bien. p.ej:

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

NO. Y no puedo encontrar ninguna forma de desactivar este error.

@SephReed : He gastado 200 puntos de representante en StackOverflow y alguien contribuyó con esta solución muy simple para importar ../package.json . Todo lo que tienes que hacer es colocar un archivo typings.d.ts en el mismo directorio que package.json , con este contenido:

declare module '*.json';

No tengo idea de cómo funciona esto, pero honestamente, no me importa. En ese momento, TS se bifurcaba por sí mismo, no por mí.

Me sorprende que este sea un debate tan acalorado. Pero entiendo el razonamiento. Para mí, por supuesto, tengo la carpeta de origen, pero también tengo scripts de compilación fuera de esa carpeta que no están destinados a ser compilados, pero definitivamente incluyen soporte de tipos, porque seamos honestos, su mejor IntelliSense es 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

Entonces uso "rootDir": "src" para asegurarme de que los archivos se dirijan a dist y no a dist/src . Pero, por supuesto, a TypeScript le gusta quejarse de esta configuración, pero como utilizo Webpack no me falla.

Finalmente entendí lo que significa exactamente esta bandera sin varios comentarios que no lo aclaran más. Solo aplaude con esto.

Las opciones que configuran carpetas y archivos para que tsc los tenga en cuenta en la conformidad: "archivos", "incluir", "excluir".

Entonces, ¿para qué usas "rootDir"?
rootDir es la raíz de la estructura de directorio (jerarquía) de sus archivos de origen, que tsc usa para emitir la misma estructura de directorio comenzando desde el directorio tsconfig.json o "outDir" si se especifica. Así que esta no es la ruta que usa tsc como ruta base para "outDir". "outDir" es solo la raíz que tsc emite archivos de salida.
Por ejemplo, digamos que su proyecto java tiene esta estructura de directorio.

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

Cuando establece "incluir" y "rootDir" como se muestra a continuación, tsc generará la salida como:

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

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

Cuando también establece "outDir" como se muestra a continuación, tsc generará la salida 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

Probablemente quisiera tener esto configurando la opción "rootDir" y cambiando la opción "outDir" como se muestra a continuación.

"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

Entonces, cuando ha configurado la opción "rootDir" que no cubre los alcances de los archivos excepto la opción "excluir", tsc no se puede compilar porque no tiene sentido con el propósito de la opción "rootDir".

Sí, es completamente una mala práctica para nombrar. Debería haber sido simplemente "rootOfStructureOfInputs" o algo así. Y también, "outDir" debería haber sido simplemente "rootOfOutputs".

Lo que ve en la SS no es un problema de WebStorm, proviene de TS DevServer.
La segunda importación recomendada es una mierda. Se toma de la carpeta de origen de "comunicación". No sé quién diablos debería querer eso. La compilación de un archivo con tal importación produce muchos problemas.

También probé:

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

Tampoco resolvió el problema

Bildschirmfoto 2020-07-22 um 10 08 28

@mhegazy Has etiquetado este problema con "Funciona según lo previsto", pero eso no es cierto. Como puede ver en mi captura de pantalla, tsc-server proporciona archivos fuera de mi rootDir (en este caso mobiservice / src) como sugerencia de importación. Para mí esto parece un error ...

¿Fue útil esta página
0 / 5 - 0 calificaciones