Ajuste la línea literal de la plantilla larga a varias líneas sin crear una nueva línea en la cadena

142

En los literales de plantilla es6, ¿cómo se puede ajustar un literal de plantilla largo a varias líneas sin crear una nueva línea en la cadena?

Por ejemplo, si haces esto:

const text = `a very long string that just continues
and continues and continues`

Luego creará un nuevo símbolo de línea para la cadena, como si se interpretara que tiene una nueva línea. ¿Cómo se puede ajustar la plantilla larga literal a varias líneas sin crear la nueva línea?

Ville Miekk-oja
fuente
2
FWIW las continuaciones de línea son difíciles de leer y frágiles contra espacios inesperados, por lo que prefiero la solución de Monte Jones sobre la de Codingintrigue. FWIW, la guía de estilo de Google recomienda la solución Monte Jones y la guía AirBnB recomienda usar una línea muy larga en su lugar, es decir, tampoco recomienda la continuación de la línea. FWIW, no pude encontrar este tema en una revisión rápida de otras guías de estilo.
Tom O'Neill el

Respuestas:

192

Si introduce una continuación de línea ( \) en el punto de la nueva línea en el literal, no creará una nueva línea en la salida:

const text = `a very long string that just continues\
and continues and continues`;
console.log(text); // a very long string that just continuesand continues and continues
CodificaciónIntriga
fuente
1
No estoy seguro de entender lo que quieres decir. ¿Puede proporcionar un ejemplo REPL ?
CodingIntrigue
1
No es fácil, en mi caso, ya que diferentes variables son tomadas de los archivos de configuración CoffeeScript etc .. mm .. parece que funciona de otra manera, pero por alguna razón se añade el espacio vacío que hay
Ville Miekk-Oja
1
Si usa una continuación de línea en la primera línea, no funciona para mí (nodo v7)
Danielo515
2
Si está utilizando esto en la prueba, a veces no devuelve la misma cadena. He resuelto mis dolores de cabeza usando deline que es sólo una1.1k Airbnb library
iarroyo
45
Esta solución no funciona bien con las sangrías (y las sangrías son comunes en el desarrollo). El carácter después de \ en la nueva línea tiene que ser el primer carácter en esa línea. Es decir, and continues...tiene que comenzar desde la posición 0 en la nueva línea, rompiendo la regla de sangría.
KingJulian
54

Este es uno viejo. Pero surgió. Si deja espacios en el editor, los colocará allí.

if
  const text = `a very long string that just continues\
  and continues and continues`;

solo haz el símbolo + normal

if
  const text = `a very long string that just continues` +
  `and continues and continues`;
Monte Jones
fuente
Bien, pero parte de la razón por la que uso esto es para evitar el símbolo '+'. Hace que el código sea más difícil de leer y más molesto de trabajar.
dgo
21

Podrías comer los saltos de línea dentro de tu plantilla literal.

// Thanks to https://twitter.com/awbjs for introducing me to the idea
// here: https://esdiscuss.org/topic/multiline-template-strings-that-don-t-break-indentation

const printLongLine = continues => {
    const text = `a very long string that just ${continues}${''
                 } and ${continues} and ${continues}`;
    return text;
}
console.log(printLongLine('continues'));

Doug Coburn
fuente
3
Este es un muy buen truco, pero falla si tiene un formateador (como prettier) configurado en su IDE. prettierenvuelve esto de nuevo a una sola línea.
Rvy Pandey
11

EDITAR : He creado un pequeño módulo NPM con esta utilidad. Funciona en la web y en Node y lo recomiendo ampliamente sobre el código en mi respuesta a continuación, ya que es mucho más robusto. También permite preservar nuevas líneas en el resultado si las ingresa manualmente como \n, y proporciona funciones para cuando ya usa etiquetas literales de plantilla para otra cosa: https://github.com/iansan5653/compress-tag


Sé que llego tarde para responder aquí, pero la respuesta aceptada todavía tiene el inconveniente de no permitir sangrías después del salto de línea, lo que significa que aún no puede escribir código de aspecto agradable simplemente escapando de las nuevas líneas.

En cambio, ¿por qué no usar una función literal de plantilla etiquetada ?

function noWhiteSpace(strings, ...placeholders) {
  // Build the string as normal, combining all the strings and placeholders:
  let withSpace = strings.reduce((result, string, i) => (result + placeholders[i - 1] + string));
  let withoutSpace = withSpace.replace(/\s\s+/g, ' ');
  return withoutSpace;
}

Luego puede etiquetar cualquier plantilla literal en la que desee tener saltos de línea:

let myString = noWhiteSpace`This is a really long string, that needs to wrap over
    several lines. With a normal template literal you can't do that, but you can 
    use a template literal tag to allow line breaks and indents.`;

Esto tiene el inconveniente de posiblemente tener un comportamiento inesperado si un futuro desarrollador no está acostumbrado a la sintaxis de la plantilla etiquetada o si no usa un nombre de función descriptivo, pero por ahora parece ser la solución más limpia.

Ian
fuente
8

Otra opción es usar Array.join, así:

[
    'This is a very long string. ',
    'It just keeps going ',
    'and going ',
    'and going ',
    'and going ',
    'and going ',
    'and going ',
    'and going',
].join('')
Liran H
fuente
3

Usa lo viejo y lo nuevo. Los literales de plantilla son geniales, pero si desea evitar largos literales para tener líneas de código compactas, conéctelos y ESLint no causará problemas.

const text = `a very long string that just continues`
  +` and continues and continues`;
console.log(text);
Raymond Wachaga
fuente
1

Similar a la respuesta de Doug, esto es aceptado por mi configuración TSLint y no se ve afectado por mi formateador automático IntelliJ:

const text = `a very long string that just ${
  continues
} and ${continues} and ${continues}`
Daniel K
fuente
0

La solución propuesta por @CodingIntrigue no me funciona en el nodo 7. Bueno, funciona si no uso una continuación de línea en la primera línea, de lo contrario falla.

Probablemente esta no sea la mejor solución, pero funciona sin problemas:

(`
    border:1px solid blue;
    border-radius:10px;
    padding: 14px 25px;
    text-decoration:none;
    display: inline-block;
    text-align: center;`).replace(/\n/g,'').trim();
Danielo515
fuente