Avvolgere la linea letterale del modello lungo su multilinea senza creare una nuova linea nella stringa


142

In letterali modello es6, come si può avvolgere un modello lungo letterale in multilinea senza creare una nuova linea nella stringa?

Ad esempio, se lo fai:

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

Quindi creerà un nuovo simbolo di linea per la stringa, come interpretandolo per avere una nuova linea. Come si può avvolgere letteralmente il modello lungo su più righe senza creare la nuova riga?


2
FWIW le continuazioni di linea sono difficili da leggere e fragili contro spazi inaspettati, quindi preferisco la soluzione Monte Jones a quella di Codingintrigue. FWIW, la guida di stile di Google consiglia la soluzione Monte Jones e la guida di AirBnB consiglia invece di utilizzare solo una linea molto lunga, ovvero, né di raccomandare continuazioni di linea. FWIW, non sono riuscito a trovare questo argomento in un rapido controllo di altre guide di stile.
Tom O'Neill,

Risposte:


192

Se si introduce una continuazione di riga ( \) nel punto della nuova riga nel valore letterale, non verrà creata una nuova riga nell'output:

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

1
Non sono sicuro di aver capito cosa intendi. Potete fornire un esempio REPL ?
CodingIntrigue

1
Non facilmente nel mio caso, dal momento che diverse variabili sono tratte da file di configurazione del coffeescript ecc. Mm .. sembra che funzioni diversamente, ma per qualche motivo aggiunge spazio vuoto lì
Ville Miekk-oja,

1
Se si utilizza una continuazione di riga sulla prima riga non funziona per me (nodo v7)
Danielo515

2
Se lo stai usando in test a volte non restituisce la stessa stringa. Ho risolto i miei mal di testa utilizzando Deline che è solo un1.1k Airbnb library
iarroyo

45
Questa soluzione non funziona bene con i rientri (e i rientri sono comuni nello sviluppo). Il carattere dopo il \ sulla nuova riga deve essere il primo carattere su quella riga. Ciò significa che and continues...deve iniziare dalla 0a posizione sulla nuova riga, infrangendo la regola del rientro.
King Julul

54

Questo è vecchio. Ma è venuto fuori. Se lasci degli spazi nell'editor, li inserirai.

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

basta fare il normale simbolo +

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

Bene, ma parte del motivo per cui lo uso è evitare il simbolo "+". Rende il codice più difficile da leggere e più fastidioso con cui lavorare.
dal

21

Potresti semplicemente mangiare le interruzioni di riga all'interno del tuo modello letterale.

// 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'));


3
Questo è un ottimo trucco, ma fallisce se hai un formatter abbastanza (come prettier) configurato nel tuo IDE. prettierlo riassume su una sola riga.
Rvy Pandey,

11

EDIT : ho creato un piccolo modulo NPM con questa utility. Funziona sul web e in Node e lo consiglio vivamente sopra il codice nella mia risposta di seguito in quanto è molto più robusto. Permette anche di preservare le nuove righe nel risultato se le inserisci manualmente come \ne fornisce funzioni per quando usi già i tag letterali del modello per qualcos'altro: https://github.com/iansan5653/compress-tag


So che sono in ritardo per rispondere qui, ma la risposta accettata ha ancora lo svantaggio di non consentire rientri dopo l'interruzione di riga, il che significa che non è ancora possibile scrivere un codice molto bello semplicemente sfuggendo a nuove righe.

Invece, perché non utilizzare una funzione letterale modello con tag ?

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;
}

Quindi puoi semplicemente taggare qualsiasi modello letterale in cui vuoi avere interruzioni di riga:

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.`;

Ciò ha lo svantaggio di avere probabilmente comportamenti imprevisti se uno sviluppatore futuro non è abituato alla sintassi del modello con tag o se non si utilizza un nome di funzione descrittivo, ma per ora sembra la soluzione più pulita.


8

Un'altra opzione è quella di utilizzare Array.join, in questo modo:

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

3

Usa il vecchio e il nuovo. I letterali dei template sono fantastici, ma se vuoi evitare i letterali lunghi in modo da avere linee di codice compatte, concatenali e ESLint non causerà confusione.

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

1

Simile alla risposta di Doug, questo è accettato dalla mia configurazione TSLint e rimane intatto dal mio auto-formatter IntelliJ:

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

0

La soluzione proposta da @CodingIntrigue non funziona per me sul nodo 7. Bene, funziona se non utilizzo una continuazione di riga sulla prima riga, altrimenti fallisce.

Questa probabilmente non è la soluzione migliore, ma funziona senza problemi:

(`
    border:1px solid blue;
    border-radius:10px;
    padding: 14px 25px;
    text-decoration:none;
    display: inline-block;
    text-align: center;`).replace(/\n/g,'').trim();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.