94

I have a long string, which I build using ES6 template strings, but I want it to be without line breaks:

var string = `As all string substitutions in Template Strings are JavaScript
              expressions, we can substitute a lot more than variable names.
              For example, below we can use expression interpolation to 
              embed for some readable inline math:`

console.log(string);

Result:

As all string substitutions in Template Strings are JavaScript
expressions, we can substitute a lot more than variable names.
For example, below we can use expression interpolation to
embed for some readable inline math:

My expectations:

As all string substitutions in Template Strings are JavaScript expressions, we can substitute a lot more than variable names. For example, below we can use expression interpolation to embed for some readable inline math:
Eugene Mihaylin
  • 1,736
  • 3
  • 16
  • 31
dim0_0n
  • 2,404
  • 5
  • 27
  • 46
  • 16
    escape the line break with a slash `\\` and it will disappear in the output, even in template strings. – dandavis Jun 23 '16 at 20:28
  • Near duplicate of https://stackoverflow.com/questions/37321047/wrap-long-template-literal-line-to-multiline-without-creating-a-new-line-in-the – Doug Coburn Jul 17 '18 at 19:20

8 Answers8

154

This is insane.

Almost every single answer here suggest running a function runtime in order to well-format, buildtime bad-formatted text oO Am I the only one shocked by that fact, especially performance impact ???

As stated by @dandavis, the official solution, (which btw is also the historic solution for unix shell scripts), is to escape the carriage return, well, with the escape character : \

`foo \
bar` === 'foo bar'

Simple, performant, official, readable, and shell-like in the process

TheLandolorien
  • 568
  • 4
  • 11
Cyril CHAPON
  • 3,556
  • 4
  • 22
  • 40
  • 3
    This works, you're escaping the cariage return, not the further spaces – Cyril CHAPON Jul 04 '18 at 10:14
  • 2
    There are no "further spaces" nor "code indentation" needed. "The way to do this" is not doing this, and following code standards. The common way you see that in a code editor (i.e those automatically returning to the line) is not to re-indent like the previous line, it goes to the line and that's it (0 indentation). If you really want to indent it, go and try, HTML prints only one escape character anyway. If you really really don't want to have x espace characters, even if HTML auto-parses it, pre-process your code with a tool that does that, but please don't run it runtime for god sake – Cyril CHAPON Jul 18 '18 at 10:12
  • 8
    No luck with this. – lwdthe1 Mar 16 '20 at 22:02
  • Using VScode this creates a tabbed space... – Andrew Nov 11 '21 at 23:44
35

A line break is a line break... If you produce them manually, I find very expectable that you get them during run-time.

BTW, I find three workarounds for now:

  1. Configure your IDE or code editor to do word wrap so you won't need to add line breaks in your code if you don't need them: your editor will break your code in two or more lines if each code sentence goes beyond configured maximum characters.

  2. Remove line breaks with String.prototype.replace:

var string = `As all string substitutions in Template Strings are JavaScript
expressions, we can substitute a lot more than variable names.
For example, below we can use expression interpolation to
embed for some readable inline math:`.replace(/\n/gm,"");

Caution: here you're running a function runtime to format your buildtime code, which might look like an anti-pattern, and have performance impact

  1. Perform these code line breaks using concatenations:
var string = `As all string substitutions in Template Strings are JavaScript`
              + `expressions, we can substitute a lot more than variable names.`
              + `For example, below we can use expression interpolation to` 
              + `embed for some readable inline math:`;

In my case, I would go with #1 option.

Cyril CHAPON
  • 3,556
  • 4
  • 22
  • 40
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
25

If you have ES6, you can use tags. For instance, the stripIndent tag from the common-tags library:

Install via:

npm install common-tags --save

Require via:

const stripIndent = require('common-tags/lib/stripIndent')

Use as:

stripIndent`
  As all string substitutions in Template Strings are JavaScript
  expressions, we can substitute a lot more than variable names.
  For example, below we can use expression interpolation to
  embed for some readable inline math:        
`

Edit: As mentioned in the comments, you likely need to pick the: const oneLine = require('common-tags/lib/oneLine') tag for your desired outcome.

More info on the aforementioned common-tags link as well as on this blog

kvz
  • 5,517
  • 1
  • 42
  • 33
  • 4
    +1 for the library and mention of ES6 tags. In this case, however, I think OP would need the [`oneLine`](https://github.com/declandewet/common-tags#oneline) tag from the `common-tags` library. – lando Jan 05 '18 at 18:25
  • 2
    Running a runtime function for code formatting purpose... Downvote. Although the lib is pretty useful, and thanks for sharing it; for this special use case, he states that he "builds the string using es6 template", means buildtime.. Performance impact ? – Cyril CHAPON Mar 08 '18 at 08:10
20
  • Either configure IDE to make wraps and use template string 1-liner, as in your 1st code snippet.

  • Either use \ escape literal char just before the line breaks.

    Example:

    const string = `1st line\
    2nd line\ 
    3rd line`; 
    

    But it will not save you from issues with space-aligning.

  • Either use old-school ES5 concatenation with '+'.

    Example:

    const string = '1st line' + 
                   '2nd line' + 
                   '3rd line'; 
    
  • Either use hack with template empty string var ${''}:

    Example:

    const string = `1st line${'' 
                   }2nd line${'' 
                   }3rd line`;
    

The 1st way is much more better, cause:

  • less symbols (size aspect)
  • no runtime operations (perfomance aspect)
RobC
  • 22,977
  • 20
  • 73
  • 80
Eugene Mihaylin
  • 1,736
  • 3
  • 16
  • 31
13

I personally prefer the look of joining an array instead:

var string = [
  `As all string substitutions in Template Strings are JavaScript`,
  `expressions, we can substitute a lot more than variable names.`,
  `For example, below we can use expression interpolation to`,
  `embed for some readable inline math:`
].join(' ');
jaybee
  • 2,240
  • 14
  • 20
  • 2
    This method is also faster than concatenations using `+`, since this only creates one internal StringBuilder for the whole set instead of one for each concatenation (though this is a micro optimization) – Vinno97 Jan 15 '18 at 08:55
  • 2
    Running a runtime function for code formatting purpose... Downvote. Performance impact ? – Cyril CHAPON Mar 08 '18 at 08:10
  • @CyrilCHAPON is the performance really going to hinder the user experience to the point that the readability of this code warrants a downvote? – Yatrix Aug 31 '18 at 12:03
  • Imagine that for 10000 strings you have your answer – Cyril CHAPON Sep 04 '18 at 08:09
  • @CyrilCHAPON Is this a part of a large and complex algorithm that needs to be micro-optimized? If not, then the answer is no. There is no point in imagining the use-case if the OP knows his. – Devin Fields Oct 09 '18 at 18:02
  • @DevinFields before thinking of micro-optimization, first maybe one should think about micro-proper-coding. It's not about "a common practise that could be optimized", it's about "an heresy that could be avoided". "Optimization" is the wrong word for this, and spelling it for that kind of practise leaves junior beginners with potentialy dangerous false ideas. – Cyril CHAPON Oct 10 '18 at 07:50
  • @CyrilCHAPON "a heresy" wow, that is quite dogmatic. I fully agree there is no reason to use template strings here (nor in your answer, for that matter), and I would upvote your answer as it is well-explained and works, but so long as the use-case isn't ridiculously huge, I am fine with someone using a join for a paragraph if it reads better to their eyes than a bunch of carriage returns. It is great to explain to them the issue, though, so I am glad this was brought up. – Devin Fields Oct 10 '18 at 16:55
  • @DevinFields you're right that I'm being dogmatic here, but this is more like I'm 1vs4 on a topic that everyone seem to consider as a "normal thing" to run code runtime for a bad-formated string at build-time. I feel like someone has to be shocking on that topic, be it just to reach beginners eyes and balance the voice of 4 peoples voting for what I call an heresy. – Cyril CHAPON Oct 11 '18 at 07:48
  • 2
    To spell this differently, this is more like a "concept-heresy", the practise in itself, that I'm pointing at. This is definaly conceptualy a bad practise, and one could simply learn to use right tools for the right thing. IDE configuration for "what they see as a developer", transpilers and pre-processors to make build-time purpose things, and leave runtime for the, well.. run-time stuff. – Cyril CHAPON Oct 11 '18 at 07:50
  • @CyrilCHAPON You make a good point. Thanks for explaining all this. It is useful. – Devin Fields Oct 11 '18 at 17:04
  • @Vinno97 That has not been true for over a decade. Straight string concatenation is faster. See https://stackoverflow.com/questions/51185/are-javascript-strings-immutable-do-i-need-a-string-builder-in-javascript/4717855#4717855 Downvoted because it was also meant to be an optimization and it actually worsens performance. – Ruan Mendes Dec 31 '19 at 15:58
  • 1
    @JuanMendes I easily believe that browsers can optimize this by now, but they only do that on consecutive runs. Also, I just ran the last JSPerf link in the comment you linked and joining arrays was still faster in Firefox 71.0. Difference was negligible though. – Vinno97 Jan 02 '20 at 19:51
  • @Vinno97 Exactly my point. I find string concatenation simpler, but there's no need for you to mention performance if you prefer the syntax of `Array.join`. Just don't mislead people into believing an old myth. – Ruan Mendes Jan 02 '20 at 21:04
3

Although it's not the typical usage for template strings, it's worth mentioning. You can just make use of the string interpolation, it can be as simple as this


const str = `some long text on ${
    "multiple" } lines without any extra ${
    "spaces" } or line breaks and readable.`;

console.log(str);
// "some long text on multiple lines without any extra spaces or line breaks and readable."

Shaaer
  • 527
  • 5
  • 17
2

For paragraphs, you can use the \s+ regex to replace white space runs with a single space so it will work for line breaks as well as the indentations. So, in your case, just add .replace(/\s+/gm, ' ') at the end.

var string = `As all string substitutions in Template Strings are JavaScript
              expressions, we can substitute a lot more than variable names.
              For example, below we can use expression interpolation to 
              embed for some readable inline math:`.replace(/\s+/gm, ' ');

console.log(string);
L. Holanda
  • 4,432
  • 1
  • 36
  • 44
  • 1
    Running a runtime function for a buildtime task is a performance heresy. Using a preprocessor or a decent IDE is a better idea. – Cyril CHAPON Aug 26 '22 at 07:58
0

In ES6, I prefer using a combination of the two top answers here (\ in combination with .replace()). The benefit of combining the replace function with the escape character means you can keep your codeblock consistently formatted with the rest of your code.

/\s{2}/g is a regular expression selecting any instance of two or more back-to-back spaces.

const myMessage = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id urna \
    ligula. Suspendisse lobortis ex ut vestibulum venenatis. Donec imperdiet ante odio, \
    nec malesuada diam tristique eget. Lorem ipsum dolor sit amet, consectetur adipiscing \
    elit. Cras in vulputate tellus.`
  .replace(/\s{2,}/g, "");

This outputs a plain, unbroken string.

"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id urna ligula. Suspendisse lobortis ex ut vestibulum venenatis. Donec imperdiet ante odio, nec malesuada diam tristique eget. Lorem ipsum dolor sit amet, consectetur elit. Cras in vulputate tellus."

L. Holanda
  • 4,432
  • 1
  • 36
  • 44
Epoch
  • 656
  • 4
  • 16
  • Running a runtime function for a buildtime task is a performance heresy. Using a preprocessor or a decent IDE is a better idea. – Cyril CHAPON Aug 26 '22 at 07:58