Enveloppez la longue ligne littérale du modèle en multiligne sans créer de nouvelle ligne dans la chaîne


142

Dans les littéraux de modèle es6, comment peut-on envelopper un long littéral de modèle en multiligne sans créer une nouvelle ligne dans la chaîne?

Par exemple, si vous faites ceci:

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

Ensuite, il créera un nouveau symbole de ligne dans la chaîne, en l'interprétant comme ayant une nouvelle ligne. Comment peut-on envelopper le long modèle littéral en plusieurs lignes sans créer la nouvelle ligne?


2
FWIW les continuations de ligne sont difficiles à lire et cassantes contre les espaces inattendus, donc je préfère la solution Monte Jones à celle de Codingintrigue. FWIW, le guide de style Google recommande la solution Monte Jones et le guide AirBnB recommande d' utiliser simplement une très longue ligne à la place - c'est-à-dire qu'aucun des deux ne recommande les continuations de ligne. FWIW, je n'ai pas trouvé ce sujet dans une vérification rapide des autres guides de style.
Tom O'Neill

Réponses:


192

Si vous introduisez une ligne continuation ( \) au point de la nouvelle ligne dans le littéral, cela ne créera pas de nouvelle ligne en sortie:

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
Je ne suis pas sûr de comprendre ce que tu veux dire. Pouvez-vous fournir un exemple de REPL ?
CodingIntrigue

1
Pas facilement dans mon cas, puisque différentes variables sont extraites des fichiers de configuration de coffeescript etc. mm .. il semble que cela fonctionne autrement mais pour une raison quelconque, il y ajoute un espace vide
Ville Miekk-oja

1
Si vous utilisez une continuation de ligne sur la première ligne, cela ne fonctionne pas pour moi (nœud v7)
Danielo515

2
Si vous l'utilisez dans le test, il ne renvoie parfois pas la même chaîne. J'ai résolu mes maux de tête en utilisant deline qui est juste un1.1k Airbnb library
iarroyo

45
Cette solution ne fonctionne pas correctement avec les retraits (et les retraits sont courants dans le développement). Le caractère après le \ sur la nouvelle ligne doit être le premier caractère de cette ligne. Cela signifie que le and continues...doit commencer à partir de la 0ème position sur la nouvelle ligne, rompant ainsi la règle de retrait.
KingJulian

54

C'est un vieux. Mais c'est venu. Si vous laissez des espaces dans l'éditeur, il les y placera.

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

faites simplement le symbole normal +

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

Bien, mais une des raisons pour lesquelles j'utilise ceci est d'éviter le symbole «+». Cela rend le code plus difficile à lire et plus ennuyeux à utiliser.
dgo

21

Vous pouvez simplement manger les sauts de ligne dans votre modèle littéral.

// 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
C'est un très bon hack, mais il échoue si vous avez un joli formateur (comme prettier) configuré dans votre IDE. prettierenroule cela en une seule ligne.
Rvy Pandey

11

EDIT : J'ai fait un petit module NPM avec cet utilitaire. Cela fonctionne sur le Web et dans Node et je le recommande vivement sur le code de ma réponse ci-dessous car il est beaucoup plus robuste. Il permet également de conserver les nouvelles lignes dans le résultat si vous les saisissez manuellement comme\n , et fournit des fonctions lorsque vous utilisez déjà des balises littérales de modèle pour autre chose: https://github.com/iansan5653/compress-tag


Je sais que je suis en retard pour répondre ici, mais la réponse acceptée a toujours l'inconvénient de ne pas autoriser les retraits après le saut de ligne, ce qui signifie que vous ne pouvez toujours pas écrire du code très beau simplement en échappant aux nouvelles lignes.

Au lieu de cela, pourquoi ne pas utiliser une fonction littérale de modèle étiqueté ?

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

Ensuite, vous pouvez simplement marquer n'importe quel littéral de modèle dans lequel vous souhaitez avoir des sauts de ligne:

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

Cela présente l'inconvénient d'avoir un comportement inattendu si un futur développeur n'est pas habitué à la syntaxe du modèle étiqueté ou si vous n'utilisez pas de nom de fonction descriptif, mais cela semble être la solution la plus propre pour le moment.


8

Une autre option consiste à utiliser Array.join, comme ceci:

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

3

Utilisez l'ancien et le nouveau. Les modèles littéraux sont excellents, mais si vous voulez éviter les longs littéraux afin d'avoir des lignes de code compactes, concaténez-les et ESLint ne causera pas de problème.

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

1

Similaire à la réponse de Doug, cela est accepté par ma configuration TSLint et reste intact par mon formateur automatique IntelliJ:

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

0

La solution proposée par @CodingIntrigue ne fonctionne pas pour moi sur le nœud 7. Bon, ça marche si je n'utilise pas de continuation de ligne sur la première ligne, ça échoue sinon.

Ce n'est probablement pas la meilleure solution, mais cela fonctionne sans problème:

(`
    border:1px solid blue;
    border-radius:10px;
    padding: 14px 25px;
    text-decoration:none;
    display: inline-block;
    text-align: center;`).replace(/\n/g,'').trim();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.