Tslint: Regla de sangría que no informa ni corrige infracciones de tamaño de sangría

Creado en 23 may. 2017  ·  66Comentarios  ·  Fuente: palantir/tslint

Informe de error

  • __TSLint versión__: 5.3.2
  • __Versión de TypeScript__: 2.3.2
  • __Ejecutando TSLint a través de__: CLI

El código de TypeScript está entretejido

export function foo() {
  return 123;
}

con tslint.json configuración:

{
  "extends": ["tslint:latest"],
  "rules": {
    "indent": {
      "options": ["spaces", 4]
    }
  }
}

Comportamiento real

Sin errores con tslint . Sin correcciones con tslint --fix .

Comportamiento esperado

Errores informados con tslint , correcciones aplicadas con tslint --fix para que el archivo resultante se vea así:

export function foo() {
    return 123;
}

2723 no funcionó como esperaba. El problema parece ser que solo se informa de una falla si se usa el carácter de espacio en blanco incorrecto, no si el tamaño de la sangría está apagado (como en mi ejemplo). fuente relevante .

Available in ESLint Formatting rule P2 Declined Bug

Comentario más útil

Estoy experimentando el mismo problema. La siguiente regla detectará las pestañas que se utilizan en lugar de los espacios, pero no detectará un número incorrecto de espacios. Puedo cambiar 2 a cualquier otro número y todavía no obtengo errores. Estoy usando tslint 5.5.0.

"indent": [true, "spaces", 2],

Todos 66 comentarios

@adidahiya Vea este comentario de @ nchen63.

Desde @ nchen63 :

Corrige pestañas -> espacios xy espacios x -> pestañas, pero no arregla espacios x -> espacios y

Sin embargo, DEBE hacer x spaces a y spaces .

Mi proyecto usa 2 y 4 espacios. Fijar la regla x spaces en y spaces sería muy útil.

También encontré este problema esperando que solucionara las violaciones de tamaño, o al menos las informe como errores para poder corregirlas. Por el momento, parece que la configuración para el tamaño de la sangría documentada en el sitio (https://palantir.github.io/tslint/rules/indent/) en realidad no hace nada.

Sí, corrija este error. Angular CLI usa 2 espacios para un nivel de sangría al generar un archivo o un proyecto, y todas las comillas son comillas simples. Luego ejecuta tslint para corregirlos de acuerdo con el tslint.json del usuario. Las comillas funcionan bien (transformándose en comillas dobles según mi preferencia), pero la sangría se mantiene en 2 espacios (mientras que yo prefiero 4). Tslint solo informa un error si ve un carácter TAB real, pero parece razonable que también debería verificar el número de espacios

Me parece que la implementación que se usa en https://github.com/palantir/tslint/blob/master/src/rules/indentRule.ts es bastante ingenua, y no esperaría que funcione por x spaces -> y spaces . El enfoque parece estar bien con las pestañas, según el comentario aquí, pero no puedo ver este enfoque como viable para los espacios.

Digamos, por ejemplo, que se eligió un ancho de sangría de 2 espacios y considere este código:

foo = {
    a: {
  b: {
    c: 'c'
  }
    },
    d: 'd'
}

¿Cómo sabría nuestra implementación actual si falla en absoluto? Cada secuencia de espacios pasa la expresión regular / / . Incluso si buscáramos múltiplos de 2 espacios, esto pasaría. De manera similar, en escenarios de sangría de varios niveles, 4 espacios iniciales podrían ser un escenario pasajero, mientras que comenzar un solo nivel de sangría con 4 espacios debería fallar.

Creo que cualquier solución necesitaría atravesar el AST, similar a lo que hace eslint (https://github.com/eslint/eslint/blob/master/lib/rules/indent.js). La desventaja de eso sería que sufriríamos un ligero impacto en el rendimiento por tabs -> spaces o spaces -> tabs . Podríamos evitar eso eligiendo la implementación basada en la configuración, pero anticipo que la implementación actual fallará si se usa una combinación de pestañas y espacios, en cuyo caso solo deberíamos usar la solución basada en AST.

Creo que al menos parte del trabajo de AST realizado en la implementación de eslint puede ser manejado directamente por la biblioteca de mecanografiado, por lo que la solución no debería ser demasiado difícil de escribir.

¿Cómo sabría nuestra implementación actual si falla en absoluto?

No es _técnicamente_ necesario. La regla align evitaría que escribas un código como ese. Claro, también podríamos caminar el AST en la regla indent . Lo único que me importa es que alguna combinación de indent y align me permita lograr lo que escribí en la descripción del problema.

La regla de alineación le impediría escribir código como ese.

¡Agradable! Me perdí eso cuando estaba examinando el código fuente. También echaré un vistazo allí. TBH, me gusta un poco la idea de aprovechar las reglas existentes para mantener a los demás lo más ingenuos posible.

Estoy experimentando el mismo problema. La siguiente regla detectará las pestañas que se utilizan en lugar de los espacios, pero no detectará un número incorrecto de espacios. Puedo cambiar 2 a cualquier otro número y todavía no obtengo errores. Estoy usando tslint 5.5.0.

"indent": [true, "spaces", 2],

¿Alguna actualización sobre esto? (Si alguien aún no está trabajando en una solución, estoy dispuesto a intentarlo).

@mDibyo hazlo

@mDibyo ¿Has progresado en esto?

Tengo una implementación parcial. Intentaré completarlo y poner un PR durante el fin de semana.

Solo quería advertir que este problema se ha convertido en una prioridad menor para mí desde que comencé a usar un formato más bonito con

Prettier, por otro lado, se esfuerza por encajar la mayor cantidad de código en cada línea.

¿Y si no quieres eso?

Con el ancho de impresión establecido en 120, lo más bonito puede producir un código demasiado compacto o indeseable.

Usamos 120 caracteres en nuestros proyectos.


Además, es otra dependencia más. Creo que preferiría usar las reglas regulares de TSLint.

Creo que preferiría usar las reglas regulares de TSLint.

@ glen-84 sí, está bien, por eso no estoy diciendo que debamos eliminar todas las reglas de formato de TSLint y delegar completamente a un formateador externo. Prettier es obviamente obstinado y no todo el mundo va a optar por usarlo. Este problema aún está abierto para los RP.

¿Qué está pasando con este problema?

mi pr está trabajando en progreso, en muchos casos, todavía necesita tiempo. @cyberhck

por lo que esperamos que se fusione muy pronto, entonces: mild_smiling_face:

¿Alguna actualización aquí?

¿Quizás podríamos pedir a los mantenedores del formateador mecanografiado que expongan un par de API? El paquete ya puede verificar que un archivo fuente completo esté formateado de acuerdo con la configuración en un archivo tslint.json

Sin embargo, es posible que necesite ayuda para jugar bien con la configuración del fijador de TSLint.

El problema parece ser que solo se informa de una falla si se usa el carácter de espacio en blanco incorrecto, no si el tamaño de la sangría está desactivado.

@adidahiya No puedo hacer que informe un error si se usa el carácter de sangría incorrecto. Si configuro la regla en espacios / 4 y tengo algo como:

export function foo() {
return 123;
}

o

export function foo() {
<tab>return 123;
}

No informa un error. Según su comentario original, ¿está seguro de que lo informa si es un espacio en blanco incorrecto?

¿Algún avance en esto? Solo preguntando 😝

¿Consejo? Utilice Prettier .

¿Alguien ha probado tslint-eslint-rules ?

@jscharett tslint-eslint-rules funciona con la regla ter-indent . Desafortunadamente, no cubre la sangría JSX ...

¿Alguna esperanza de una solución aquí?

Este error aún no se corrigió en v5.10.0

Debo decir que no me imagino que TSLint pueda formatear el código JS tan bien como Prettier. Este es un problema complicado y Prettier lo ha resuelto mejor que nadie. No creo que debamos depender de TSLint para esto, especialmente porque los proyectos a menudo usan ambas herramientas en conjunto y es probable que surjan conflictos ...

EDITAR: Para tener una mejor idea de _cuán_ complicado es este problema, revise este PR o eche un vistazo al código fuente de Prettier. Si estas demostraciones no le parecen "complicadas", ¡ayude a este proyecto con un PR 😄!

@aervin Tiendo a no estar de acuerdo aquí. Los 2 proyectos, en mi opinión, tienen propósitos diferentes. Prettier entra en la categoría de formato, mientras que TSLint está más en línea con la validación. Sí, TSLint puede realizar el formateo de algunas reglas, pero sus propósitos previstos como linter, se remontan a la validación.

El problema de confiar en Prettier es que tiene opiniones. Es genial si estás de acuerdo con su estilo, pero ¿y si no? Todos solíamos usar JSLint, y todos nos quejamos porque era muy obstinado. Luego vinieron JSHint y JSCS, que nos dieron algo de control. Ahora tenemos herramientas poderosas como @eslint que nos dieron la capacidad de conectar y

Si bien estoy seguro de que Prettier es un gran proyecto, personalmente lo veo como un paso atrás. Me está quitando el control. TSLint no necesita "arreglar" el código, si ese es el problema, simplemente márquelo como un problema. No dudo que este problema sea complicado, pero eslint lo resolvió. La regla solía funcionar; ¿Qué cambió para romperlo?

@jscharett Gracias por su amable respuesta. Estoy de acuerdo en que estos proyectos tienen diferentes propósitos, o _deberían_ tenerlos. Mi argumento es que deberíamos limitar estos proyectos a esos propósitos. Dejemos que Prettier solucione los problemas de sangría y dejemos que TSLint advierta a los desarrolladores sobre las funciones de flecha que pueden simplificarse.

También estoy de acuerdo en que Prettier tiene opiniones. Me gusta eso de Prettier. Ahora mi equipo no tiene que discutir qué opinión de formato es más razonable. Todos podemos quejarnos de Prettier: riendo:.

EDITAR:

La regla solía funcionar; ¿Qué cambió para romperlo?

El comentario del tema de apertura me lleva a creer que esta regla nunca funcionó como se esperaba.

Si bien estoy seguro de que Prettier es un gran proyecto, personalmente lo veo como un paso atrás. Me está quitando el control.

Mi experiencia fue que pensé que me importaba tener un control detallado sobre las reglas de formato hasta que agregué Prettier ... y poco después me di cuenta de que no me importaba tanto la forma particular en que se formateaban las cosas, sino el hecho de que se formatearon de forma coherente. Es una enorme carga cognitiva dejar de preocuparme por eso y concentrarme por completo en lo que quiero que el código _haga_ en lugar de en cómo se ve.

tslint ya valida otras cosas que entrarían en la categoría de formato. Por ejemplo, imponer alineación, estilo de corchetes o espacios entre nombres de variables y operadores. Además, es deseable poder validar la sangría sin tener que depender de una solución obstinada como más bonita.

Necesita menos discusión y más relaciones públicas. 😉😉

adelante @ffxsam

Mi comentario fue principalmente irónico. Aunque me pregunto por qué este problema tiene más de un año y no se ha avanzado. Parece que todo el mundo está discutiendo sobre linting vs Prettier.

@ffxsam Porque existe un debate sobre si tslint tiene más que ver con la parte ts o con la parte lint

Ese es un punto válido. Parece que hay cierta superposición con TSLint / ESLint. Pero el hecho es que hay una opción indent que no funciona y que se ha roto durante quién sabe cuánto tiempo. ¿Parece que lo más rápido / fácil sería que alguien familiarizado con el código base de TSLint lo arreglara ...?

Vote por arreglar x spaces => y spaces . Esta es una característica en la que nuestra empresa confía mucho. No tiene sentido simplemente no arreglar esto.

@ffxsam Estoy viendo este número durante casi un año, sí, ha pasado mucho tiempo, pero como puede ver, hay dos intentos de relaciones públicas y no funcionó hasta ahora, creo que es más difícil de lo que parece, pero de Por supuesto, para los mantenedores podría ser más fácil, solo tengo mucha paciencia: mild_smiling_face:

Todavía reproducible en el proyecto vacío
https://github.com/dimaShin/tslint-reproduce-2814

Hola @dimaShin , gracias por tomarse el tiempo para crear un repositorio reproducible. Sin embargo, el equipo ya está al tanto de este problema, la reproducción nunca fue un problema.

Solo estamos esperando esta función, posiblemente con la opción de corrección, pero eso no es un problema para mí. La última vez que verifiqué, las personas estaban usando más bonito para verificar si hay sangría y tslint para todo lo demás.

No estoy diciendo que sea una buena opción para usted, para mí ciertamente no lo es, también sugeriría usar .editorconfig para esta opción en particular y cambiar a tslint más tarde cuando esto se resuelva.

Nuevamente, gracias por tomarse el tiempo para agregar más información :)

Determinemos una estrategia para verificar la sangría. Como referencia, aquí está la estrategia que utiliza eslint:

  1. Una instancia de OffsetStorage almacena un mapa de compensaciones deseadas, donde cada token tiene un desplazamiento especificado desde otro token especificado o hasta la primera columna.
  2. A medida que se atraviesa el AST, modifique las compensaciones deseadas de tokens en consecuencia. Por ejemplo, al ingresar un BlockStatement, compensar todos los tokens en el BlockStatement por 1 nivel de sangría de la llave de apertura del BlockStatement.
  3. Después de atravesar el AST, calcule los niveles de sangría esperados de cada token de acuerdo con el contenedor OffsetStorage.
  4. Para cada línea, compare la sangría esperada del primer token con la sangría real en el archivo e informe el token si los dos valores no son iguales.

Esta estrategia se basa en la sintaxis, la cual, en base a comentarios anteriores, es demasiado obstinada porque requiere que las líneas se rompan de cierta manera. Propongo una forma simple de verificar la sangría que es independiente de cómo se divide el código en líneas:

  1. La unidad de sangría se define en la configuración. Para las pestañas, es un carácter de pestaña. Para los espacios, son dos o cuatro caracteres de espacio.
  2. La primera línea no vacía del archivo debe tener cero unidades de sangría.
  3. Cada línea subsiguiente que no esté vacía debe tener
    un. El mismo número de unidades de sangría que la línea anterior no vacía o
    B. Menor que el número de unidades de sangría como la línea anterior no vacía o
    C. Exactamente uno más que el número de unidades de sangría de la línea anterior no vacía

Algunas cosas adicionales para discutir:

  • El parámetro de tamaño no tiene ningún efecto con las pestañas (¿por qué?)
  • No hay ninguna razón por la que el parámetro de tamaño no pueda ser un número entero positivo
  • La corrección automática del tamaño de la sangría probablemente no se pueda implementar sin seguir la ruta de la estrategia de sintaxis

@stifflerus La regla también debería funcionar con la función if / for / arrow sin {} bloques

@maximelkin ¿Los ejemplos que dio no están sangrados en la segunda línea? ¿Puede dar un ejemplo de dónde fallaría la estrategia propuesta?

if(this) that(); //okay because it's all one line

if(this)
  that(); //also okay because the second line is indented

let x = () => f(); //okay because it's all one line

let y = () =>
  f(); // I have not seen any code but like this but it would be okay

Sería increíble si esto se solucionara.

No puedo creer que algo tan fundamental como hacer cumplir las reglas de sangría todavía no esté funcionando.

Entonces, ¿no hay forma de eliminar ese código ts en 2018?

const x = {
  a: 1,
   b: 2,
}

Funciona para mi
./.eslintrc.ts.js :

module.exports = {
  'parser': 'typescript-eslint-parser',
  'parserOptions': {
    'ecmaVersion': 6,
    'sourceType': 'module',
    'ecmaFeatures': {
      'jsx': true,
    }
  },
  'plugins': [
    'react',
  ],
  'rules': {
    'indent': ['error', 2],
  },
}

yarn eslint --no-eslintrc --config ./.eslintrc.ts.js --ext .tsx src

https://github.com/eslint/typescript-eslint-parser

la solución que encontré para el problema de sangría en angular es agregar más bonito con los siguientes pasos:
npm install --save-dev tslint-plugin-prettier prettier tslint-jasmine-rules
editar tslint.json ->
`" rulesDirectory ": [
"node_modules / codelyzer",
"node_modules / tslint-plugin-prettier",
"módulos_nodo / tslint-jasmine-rules / dist"

],
"extiende": "tslint-plugin-más bonito",

"reglas": {
"más bonita": cierto,
// agrega aquí tus reglas deseadas`

y en packege.json agregue ->
"," más bonita ": {
"singleQuote": verdadero,
"printWidth": 140,
"semi": verdadero,
"bracketSpacing": verdadero,
"arrowParens": "siempre",
"parser": "mecanografiado"
} "

Esta es una funcionalidad que casi todo el mundo usa a diario. Agradecería que se le prestara más atención a este tema.

Chicos, pueden usar la opción ter-indent proporcionada por tslint-eslint-rules.

"ter-indent": [verdadero, 4, {"SwitchCase": 1}]

Funcionó para mí. ¡Salud!

@hiteshaleriya, eso es lo que he tenido en mi proyecto por un tiempo, pero en realidad no está solucionando los errores, solo silenciándolos ... aquí está mi tslint.json :

{
    "extends": "tslint-config-airbnb",
    "rules": {
        "ter-indent": ["error", "spaces", 4],
        "no-unused-vars": ["warn"],
        "no-multi-spaces": false,
        "no-console": false,
        "max-line-length": false,
        "import-name": false
    }
}

y aquí hay un ejemplo relevante que terminó sin causar advertencias ni errores:

function retrieveAndSetConfig(): Promise<any> {
  return new Promise((resolve, _) => {
  // ^ 2 spaces, expected 4
    const ghe = new GHEUtils();
    // ^ 4 spaces, expected 8
    // ...
}

Tampoco muestra errores cuando se usan pestañas (¿aunque eso podría ser por diseño cuando hay 4 espacios presentes?).

@SpencerKaiser ¿Puede actualizar su regla de ter-sangría como se muestra a continuación y luego intentar:

"ter-indent": [true, 4]

Probé su ejemplo y está funcionando como se esperaba al final (causando errores).

@hiteshaleriya ¡ gracias por --fix . ¿Algunas ideas?

@SpencerKaiser ¿Puedes intentar ejecutar el comando --fix dos veces? La primera vez sangrará la primera línea solo y luego la segunda vez sangrará el resto (para su código de ejemplo). Parece extraño, pero informe el problema si no funciona.

@hiteshaleriya así que un par de observaciones ... No necesitaba ejecutarlo de nuevo, necesitaba ejecutarlo aproximadamente n/4 veces donde n es la longitud de la sangría en los espacios de la la línea con sangría más lejana del proyecto ¯ \ _ (ツ) _ / ¯

Después de finalmente terminarlos todos, parece que se está saltando errores básicos de sangría como este:

class Something {
    function myFunc() {
        const myThing = {
            wat: 1,
         wattt: 5,    // 9 spaces, expected 12
        };
    }
}

Si estropeo el nivel de sangría de const (línea 17) a 0 espacios, el resto se marca con errores _excluyendo_ la línea con el espacio cuando dejo --fix :

ERROR: 17:1  ter-indent  Expected indentation of 8 spaces but found 0.
ERROR: 18:1  ter-indent  Expected indentation of 4 spaces but found 12.
ERROR: 20:1  ter-indent  Expected indentation of 0 spaces but found 8.

Con --fix , aquí está el primer pase:

        const myThing = {
    wat: 1,
         wattt: 5,
};

Y el segundo pase:

        const myThing = {
            wat: 1,
         wattt: 5,
        };

¿¿Pensamientos??

@shubich terminé haciendo lo mismo ...

¿Hay alguna actualización sobre esto?

@MaKCbIMKo, por lo que tengo entendido, todo el equipo se moverá para integrar eslint visit typescript-eslint, y en un futuro cercano tslint quedará obsoleto, por lo que es tan bueno como ignorar esta regla por ahora (o usar tslint-config-prettier )

Cierre por la complejidad de esta tarea y el cambio de dirección del proyecto: # 4534

La regla ESLint de mecanografiado-eslint funciona perfectamente para mí (ver # 4534):

module.exports = {
    "env": {
        "browser": true,
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": 2019,
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true
        },
        "project": "./tsconfig.json",
    },
    "plugins": ["@typescript-eslint"],
    "rules": {
        "@typescript-eslint/indent": ["error", 2] // or ["error", "tab"]
    }
}

🤖 ¡Bip boop! 👉 TSLint está en desuso 👈 ¡y debería cambiar a mecanografiado-eslint ! 🤖

🔒 Este tema se está bloqueando para evitar más discusiones innecesarias. ¡Gracias! 👋

PS tslint-config-prettier : deje de usar _linters_ como TSLint para _formatear_ su TypeScript. Es mejor hacerlo con un _formateador_ como Prettier .

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