Обернуть длинную буквенную строку шаблона в многострочное, не создавая новую строку в строке

142

В шаблонных литералах es6 как можно обернуть длинный шаблонный литерал в многострочный, не создавая новую строку в строке?

Например, если вы делаете это:

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

Затем он создаст символ новой строки для строки, интерпретируя его как новую строку. Как можно обернуть длинный литерал шаблона в несколько строк без создания новой строки?

Ville Miekk-oja
источник
2
В то же время продолжения строк трудно читать и они ломкие от неожиданных пробелов, поэтому я предпочитаю решение Monte Jones, а не решение Codingintrigue. ПОЭТОМУ руководство по стилю Google рекомендует решение Monte Jones, а руководство AirBnB рекомендует использовать вместо него очень длинную линию, то есть ни один из них не рекомендует продолжения строки. FWIW, я не мог найти эту тему в быстрой проверке других руководств по стилю.
Том О'Нил

Ответы:

192

Если вы введете продолжение строки ( \) в точке новой строки в литерале, это не создаст новую строку на выходе:

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
CodingIntrigue
источник
1
Не уверен, что я понимаю, что вы имеете в виду. Можете ли вы привести пример REPL ?
CodingIntrigue
1
В моем случае это нелегко, так как разные переменные берутся из конфигурационных файлов coffeescript и т. Д. Мм .. кажется, что это работает иначе, но по какой-то причине он добавляет пустое место
Ville Miekk-oja
1
Если вы используете продолжение строки в первой строке, оно не работает для меня (узел v7)
Danielo515
2
Если вы используете это в тесте, иногда он не возвращает ту же строку. Я решил свои головные боли, используя deline, который просто1.1k Airbnb library
iarroyo
45
Это решение не работает с отступами (и отступы распространены в разработке). Символ после \ на новой строке должен быть первым символом в этой строке. Это означает, что and continues...он должен начинаться с 0-й позиции на новой строке, нарушая правило отступа.
KingJulian
54

Это старый. Но это подошло. Если вы оставите какие-либо пробелы в редакторе, он поместит их туда.

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

просто сделай нормальный + символ

if
  const text = `a very long string that just continues` +
  `and continues and continues`;
Монте Джонс
источник
Хорошо, но отчасти я использую это, чтобы избежать символа «+». Это делает код сложнее для чтения и более раздражающим для работы.
КГВР
21

Вы можете просто съесть разрывы строк внутри литерала шаблона.

// 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
Это очень хороший взлом, но он потерпит неудачу, если prettierв вашей IDE настроен симпатичный форматер (например ). prettierоборачивает это обратно в одну строку.
Рви Пандей
11

РЕДАКТИРОВАТЬ : я сделал крошечный модуль NPM с этой утилитой. Он работает в Интернете и в Node, и я настоятельно рекомендую использовать его поверх кода, приведенного в ответе ниже, поскольку он гораздо более надежен. Он также позволяет сохранять новые строки в результате, если вы вручную вводите их как \n, и предоставляет функции для случаев, когда вы уже используете шаблонные литеральные теги для чего-то еще: https://github.com/iansan5653/compress-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;
}

Затем вы можете просто пометить любой шаблонный литерал, в котором вы хотите иметь разрывы строк:

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

Это имеет тот недостаток, что может иметь непредвиденное поведение, если будущий разработчик не привык к синтаксису тегированного шаблона или если вы не используете описательное имя функции, но на данный момент это кажется самым чистым решением.

Ян
источник
8

Другим вариантом является использование Array.join, например, так:

[
    'This is a very long string. ',
    'It just keeps going ',
    'and going ',
    'and going ',
    'and going ',
    'and going ',
    'and going ',
    'and going',
].join('')
Лиран Х
источник
3

Используйте старое и новое. Шаблонные литералы хороши, но если вы хотите избежать длинных литералов, чтобы иметь компактные строки кода, объедините их, и ESLint не вызовет суеты.

const text = `a very long string that just continues`
  +` and continues and continues`;
console.log(text);
Раймонд Вачага
источник
1

Подобно ответу Дуга, это принимается моим конфигом TSLint и остается неизменным моим автоформатером IntelliJ:

const text = `a very long string that just ${
  continues
} and ${continues} and ${continues}`
Даниэль К
источник
0

Решение, предложенное @CodingIntrigue, не работает для меня на узле 7. Что ж, оно работает, если я не использую продолжение строки в первой строке, иначе не получается.

Возможно, это не лучшее решение, но оно работает без проблем:

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