Tslint: dependencias no implícitas: mapeo de rutas de soporte

Creado en 20 oct. 2017  ·  18Comentarios  ·  Fuente: palantir/tslint

Informe de error

  • __TSLint versión__: 5.8.0
  • __Versión de TypeScript__: 2.7.0-dev.20171020
  • __Ejecutando TSLint a través de__: CLI

El código de TypeScript está entretejido

src / a.ts

import { x } from "foo";

tipos / foo.d.ts

export const x = 0;

tsconfig.json

{
    "compilerOptions": {
        "paths": {
            "*": "types/*"
        }
    }
}

con tslint.json configuración:

{
    "rules": {
        "no-implicit-dependencies": true
    }
}

Comportamiento real

ERROR: /home/andy/sample/tslint/src/a.ts[1, 19]: Module 'foo' is not listed as dependency in package.json

Comportamiento esperado

No hay error. Creo que si una importación no se resuelve en algo en node_modules esta regla debería ignorarla.

Comentario más útil

Esta regla no funciona cuando usamos un alias para nuestro propio código fuente (no para importar desde paquetes npm). Es muy útil utilizar una ruta absoluta en lugar de una ruta relativa.
En nuestro tsconfig.json, para una aplicación angular, solo tenemos que agregar:

"compilerOptions": {
  ...
  "baseUrl": "./src",
  "paths": {
    "~/env": ["environments/environment"],
    "~/*": ["app/*"]
  }
}

Entonces podemos hacer importaciones como:

import {FooService} from '~/core';
import {Environment} from '~/env';

Quizás deberíamos reabrir este problema para resolver este caso (no hay necesidad de node_modules, solo el archivo tsconfig.json).
Aprecio esta regla, por lo que será una pena desactivarla.

Todos 18 comentarios

Creo que si una importación no se resuelve en algo en node_modules, esta regla debería ignorarla.

La regla no intenta resolver los módulos. Eso significaría que necesita tener todas las dependencias instaladas, lo cual no es realmente posible con peerDependencies y OptionalDependencies. Con la implementación actual, puede eliminar un clon nuevo sin instalar nada. Supongo que eso es lo que hacen la mayoría de las herramientas de calidad de código.

Según entiendo las asignaciones de ruta, solo existen en el momento de la compilación. En tiempo de ejecución, todavía necesita el módulo instalado para que node / webpack / lo que sea para recogerlo correctamente.
Eso significa que las asignaciones de ruta solo son relevantes si tiene importaciones de solo tipo que se eliden durante la compilación. En este caso, la regla probablemente no sea la opción adecuada para usted.

En nuestro caso, generalmente no hay package.json en absoluto, así que supongo que deberíamos deshabilitar esta regla en ese momento. ¡Gracias!

En mi caso, estoy "importando" proyectos mecanografiados separados en los que estoy trabajando simultáneamente usando el mapeo de rutas:

"compilerOptions": {
    ...
    "paths": {
        "tsbase": ["../tsBaseProject/src"],
        "tslibrary": ["../tsProjectLibrary/src"]
    }
}

para poder utilizarlos en el proyecto como si fueran módulos.
¿Hay alguna forma de incluirlos en la lista blanca?

Las asignaciones de ruta de dependencies o peerDependencies a su package.json

Cuando compilo la fuente principal que "importa" los proyectos secundarios, todo se compila en un solo paquete como si fueran carpetas reales en el proyecto. No necesito tenerlos en la carpeta node_modules.
Para ser claros, en las carpetas secundarias del proyecto tengo archivos .ts reales, no solo las declaraciones de tipo.

+1 para agregar una lista blanca como en no-submodule-import

También tenemos el caso en el que usamos el caso en el que definimos un alias de ruta '~' al directorio base para evitar importaciones relativas. Este alias se resuelve más tarde mediante paquete web, caja de fusibles, etc. A partir de 5.8, tslint escupe muchos errores falsos debido a esto ...

Lo que dijo ^^

Después de actualizar, ahora tengo cientos de estos errores por las mismas razones descritas anteriormente. Una especie de regla sin sentido.

Esta regla no funciona cuando usamos un alias para nuestro propio código fuente (no para importar desde paquetes npm). Es muy útil utilizar una ruta absoluta en lugar de una ruta relativa.
En nuestro tsconfig.json, para una aplicación angular, solo tenemos que agregar:

"compilerOptions": {
  ...
  "baseUrl": "./src",
  "paths": {
    "~/env": ["environments/environment"],
    "~/*": ["app/*"]
  }
}

Entonces podemos hacer importaciones como:

import {FooService} from '~/core';
import {Environment} from '~/env';

Quizás deberíamos reabrir este problema para resolver este caso (no hay necesidad de node_modules, solo el archivo tsconfig.json).
Aprecio esta regla, por lo que será una pena desactivarla.

@ andy-ms reconsidere las rutas de soporte (lo usamos ampliamente con nx espacios de trabajo). Esta es una regla realmente útil, pero por ahora me veo obligado a desactivarla.

Intenté buscar en el código fuente y la solución tendría que ir en algún lugar a lo largo de estas líneas . También verifiqué cómo Typecript está manejando eso y lo rastreé hasta esta función . Definitivamente no es una hazaña fácil duplicar esa lógica. No estoy seguro de si esa función se puede reutilizar, hay un montón de argumentos de los que no estoy seguro.

Me gustaría mucho que esto también se solucione. El mapeo de rutas es una característica muy valorada. También intenté usar módulos vinculados como solución alternativa, pero tampoco son compatibles.

Descubrí una solución alternativa que resuelve el problema de alguna manera para mí, pero no es seguro que lo sea para todos, o que se pueda mantener en absoluto. De todos modos, la solución es la siguiente:

Agregue un paquete falso a optionalDependencies con el nombre del mapa de ruta de tsconfig.json , e instale las dependencias usando npm install --no-optional . Desafortunadamente, esto no funciona con yarn --ignore-optional ; aún falla al intentar recuperar el paquete.

Entonces, con rutas en tsconfig.json parecidas a esto:

    "paths": {
        "~/*": ["src/*"],
        "some-path/*": ["whatever/*"]
    }

Y opcional en package.json así:

    "optionalDependencies": {
        "~": "tslint-hack",
        "some-path": "tslint-hack"
    },

Debería ser posible obtener dependencias de producción y desarrollo para instalar usando npm install --no-optional . Obviamente, esto supone que no necesita ninguna dependencia opcional instalada. También vale la pena mencionar que no lo hice funcionar con @ como nombre del paquete.

Si eliges usar este truco, probablemente sea inteligente agregar un archivo .npmrc a la raíz del proyecto, con optional=false configurado, para que puedas volver a ejecutar npm install sin la bandera --no-optional .

Otra solución que _debería_ funcionar es crear un paquete con el nombre deseado y publicarlo en un registro privado, utilizando verdaccio o similar. Creo que es posible configurar registros privados por módulo usando .npmrc o .yarnrc , y como tal debería ser mejor en términos de mantenibilidad. Sin embargo, nada de esto se prueba.

Espero que esto pueda ayudar un poco a aquellos que quieran usar esta regla tslint y mantener las resoluciones de sus módulos en su lugar. Pero no sustituye a una solución adecuada.

También tiene este problema, lo que hace que la sonda lo marque incorrectamente como un olor a código.

Creo que esta es una solicitud válida ya que tslint se trata de mecanografiado y las rutas son una configuración de mecanografiado válida (e importante).

¿Qué pasa si tengo el package.json en un directorio diferente al de tslint.json ?

- web
    - package.json
    - ClientApp
        - tslint.json

Estoy trabajando en una configuración similar y obtengo errores en casi todos los archivos debido a esta regla. ¿Alguna solución para esto?

La forma que he encontrado para solucionar este problema es utilizando la siguiente opción de configuración.

"no-implicit-dependencies": [true, ["src", "app", "~"]]

Incluye en la lista blanca las rutas proporcionadas. Obviamente, esto significa duplicación, pero es una solución rápida si está buscando una.

Para aquellos de nosotros que usamos @ símbolos como prefijos para rutas personalizadas, he creado un PR para corregir un pequeño error con la implementación actual # 4192

"no-implicit-dependencies": [true, ["@src", "@app", "~"]]

@ifiokjr Estaba usando @ como mi alias src, por lo que mis importaciones parecían @/components
No se pudo establecer @ como ruta ignorada ya que intentó importar @/components como un módulo completo en lugar de resolver @ primero.

Cambié mi alias a ~ y usé la línea de arriba en mi tslint, resolviendo el problema

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