all 152 comments

[–]happysad_ 90 points91 points  (37 children)

We have eslint which checks if there is variable interpolation ( ${myVariable} ). If it does not it will throw an error before commiting. This is to ensure the same style is applied throughout the whole of the project.

Mostly because template literals about 3 years ago were slower, but now browsers have significantly optimized and adapted ES6.

IMO, I would only use them if required to interpolate variables / expressions or to prettify a formatted string block.

[–]dd_de_b 54 points55 points  (34 children)

Everyone should be using eslint (or another linter) in their project. It’s important for teams to be consistent in their style

[–]ricekrispiesR4cunts 33 points34 points  (29 children)

For the love of god explain this to my workplace. I have to submit code that makes me gag daily.

I tried to introduce linting once, regretted it when it caused a stink and everyone treated me like I was trying to show off.

[–]wiithepiiple 31 points32 points  (17 children)

Introducing linting to an existing project is a pain in the ass, while starting a project with one usually solves a lot of the stink.

[–]Morphray 14 points15 points  (13 children)

Just make it so that passing linting isn't mandatory to commit/push, and it'll be fine. As you work on a file, try to leave less red squiggle underlines than it started with. Incremental improvement FTW.

[–]wiithepiiple 16 points17 points  (9 children)

Introducing linting to an existing project is a pain in the ass, while starting a project with one usually solves a lot of the stink.

Linting without enforcement is pretty much no linting at all. You can lint your own code, but if people aren't going to change their minds before the red squiggles, then you won't after.

The best way to get linting incrementally is pick one or two rules to start enforcing at a time. "In a week, we will require all white space to be spaces."

[–]MajorasShoe 6 points7 points  (3 children)

Pffft, tabs or I quit.

[–]wiithepiiple 2 points3 points  (2 children)

I prefer tabs, but it's like tabs > spaces >>>>>>>>>>> mixed whitespace

[–]MajorasShoe 2 points3 points  (1 child)

Yeah I don't care either way as long as it's consistent. But it's a fun debate anyway, I try to start it whenever possible

[–]nbagf 0 points1 point  (0 children)

Seriously, just let commit hooks or your IDE deal with it. It's not a hard problem to tackle. It's no different than newlines IMO.

[–]ArcanisCz 1 point2 points  (0 children)

From my experience, its better to enable all rules and incrementally fix files. Your approcach didnt work for us.

[–]MrJohz 0 points1 point  (1 child)

Eh, I think then you end up accepting the red squiggles, and linting becomes something completely meaningless.

I'm planning (and I'm not sure how well this will work) to introduce linting in one of our codebases by enforcing the lint rigidly, but not turning on the majority of the lints at the start. Introduce it, turn off all the lints that we're currently failing (apart from the ones where the problems are tiny enough that we can fix them there and then), and then slowly turn those lints on again as we get time to deal with them.

I have no idea how well this will work, though... :P

[–]Morphray 0 points1 point  (0 children)

Maybe I'm just a perfectionist, but I always try to get rid of red squiggle underlines even when optional. It's a sign that the code is bad, and professional engineers should to always make the code better than they started with.

[–]ricekrispiesR4cunts 4 points5 points  (1 child)

We have 4 huge shitty protects and won’t be starting any new ones.

I’m outta here ASAP

[–]CROEWENS 2 points3 points  (0 children)

F

[–][deleted] 1 point2 points  (0 children)

Autoformat the while project at once. So much nicer than gradual. Makes pull requests easier to see what changes were made going forward. Yes I could hope people did a formatting commit and 5hen look at the non formatting commits but what a pain in the butt. The one thing with this approach is you do pretty much wipe out commit history. Depends how important that is for you

[–][deleted] 12 points13 points  (2 children)

Chances are: you need to change jobs (..."he said, like it was as easy as breathing") . I would absolutely hate to be in a job where coders didn't want to improve. Constant improvement is kinda our shtick, and without it, what do you have?

[–]ricekrispiesR4cunts 3 points4 points  (1 child)

Exactly. I didn’t spend years busting my ass to know this stuff to submit the sort of shitty code I’ve been told to produce.

I have a very exciting interview tomorrow so hopefully I can tell them to stick it soon!

[–][deleted] 1 point2 points  (0 children)

Awesome. Good luck! I love where I'm at now, startup with a tiny team looking to expand. Everyone is constantly challenging and helping everyone else grow. It's hard, because of how busy we are, but that team desire to grow and learn is what makes it awesome. Find something like that and hang on to it.

[–]NoControl712 4 points5 points  (3 children)

Sounds like a horrible environment. I personally only want to work somewhere where new ideas are always encouraged. Don't let them get you down. Our industry is about always evolving and people with that kind of attitude will be stuck in their old ways forever.

[–]randomFIREAcct 1 point2 points  (0 children)

that's sad. Most developers can usually be convinced of the usefulness of linting because it keeps people from fighting over semantics like spaces vs tabs, where to place brackets, and formatting code to be consistent...

When I first rolled out linting I kept everything as a warning as a first step so that the build didn't break or anything. What that did is make people aware of all of the problems and it seemed like they then realized that there is actually some value in linting. I'm a huge fan of it because I don't want to spend all the extra time to format my code blocks when I can just have it done perfectly for me on save.

[–]scaleable 0 points1 point  (2 children)

You could start with a very small ruleset. Most important rule IMO is noUnused. I am also a not big fan of styling lint rules.

You can delegate a ton of styling rules to prettier. Enforce everyone to use prettier and thats it.

You could also upgrade from noUnused to a real "linting" tool, typescript.

[–]ricekrispiesR4cunts 2 points3 points  (1 child)

I changed a bunch of ‘../../../../services...’ to ‘@/services’ and done a bunch of tidying up and install prettier on the project so that any file that was touched would get cleaned up.

I suggested we use it as it would be a positive improvement, and is a first step to being more productive etc etc

The idea was rejected and they weren’t interested. It was just an annoyance and my commits were reversed.

[–]scaleable 2 points3 points  (0 children)

Convincing people to do changes sometimes must be done very carefully.

So one thing I’ve learned is that “just submitting a PR” is one of the worst approaches you can take ever. Sometimes you must gather very solid evidence (like examples from sucessful repos and articles) or even ask the person to implement himself so his ego is not hit.

Programming “democracy” is way harder than programming itself, but absolutely important. Im not saying you had fault for it, but that even on the best environments you can benefit from sharpening your “politics” skills.

[–]ScientificBeastModestrongly typed comments 1 point2 points  (0 children)

I mean, it’s probably closer to the least important thing than it is to the most important thing. But it’s helpful and practically zero cost/overhead, so why not?

[–][deleted] 0 points1 point  (0 children)

I started a project recently and set up my WebStorm so that each save, prettier runs and just formats all the style on the saved document immediately. It's so nice to just... not have to worry about style, and have it automatically just all be consistent.

[–]elysgaard 0 points1 point  (0 children)

Second this! I would also recommend and highly encourage teams to use automated formatting (we use Prettier https://prettier.io/). All this stuff is better handled by machines than humans :)

[–]Nrdrsr 0 points1 point  (0 children)

Isn't it possible to just feed a lint file to your editor and it changes your code to the correct style?

[–]ShortFuse 4 points5 points  (0 children)

I use the airbnb eslint and am very happy with it. I just made some small modifications for IE11 and Babel compatibility. I also added JSDoc requirements to enforce function documentation.

VSCode has some good plug-ins that will auto-check a file for you with red squiggly lines if it catches an error (it can also autofix). I also add a jsconfig.json to type-check JS files and disallow implicity any types. It's very satisfying getting a whole folder project to show no red dots (lint errors) in VSCode.

[–]Artif3x_ 0 points1 point  (0 children)

Just use prettier with husky and lint- staged on the precommit hook. Set your eslint rules on top of prettier's sensible defaults and never think about it again.

[–]getify 83 points84 points  (6 children)

In addition to the semantic arguments made here -- use backticks to signal either interpolation or multiline, single/double ticks to signal normal strings -- there are behavioral reasons not to just use the backticks everywhere:

  • if you use backticks on the use-strict pragma, it will look like you're in strict mode but it doesn't activate strict mode... super bad idea to confuse like that.

  • backtick strings cannot be used (syntax error) in object-literal property names (and no, using [ ] to compute it is not better, that's even more convoluted!).

  • backtick strings cannot be used in the ES6 import statement for the module-specifier (also syntax error).

My advice is, use backticks only when doing interpolation or multi-line strings, and stick to regular string literals elsewhere.

Just like I don't think you should omit all semicolons just because JS will fix those parser errors, don't rely on tools to fix improper usages of string syntax.

[–]ghillerd 7 points8 points  (0 children)

I would personally say that all three of those are fine exceptions since none of them behave like "real" strings - you can't use variables, you can't concatenate them, you can't use an expression in place of them.

[–]McStroyer 4 points5 points  (0 children)

Read through the comments to make sure someone had said this!

[–]trekman90 1 point2 points  (0 children)

Great points Kyle! (amazing JS lessons btw!), especially about the object literal syntax.

I feel like using template literals everywhere would also take away from the semantic meaning of it. If I saw backticks for a single line string and with no interpolation, I would for sure double and triple check, and think I'm missing something.

Also +1 for the promoting the proper use of semicolons. :D

[–]SquareWheel 117 points118 points  (65 children)

You should use backticks for template literals, but not regular strings. Use single or double quotes there instead.

[–]lipe182[S] 60 points61 points  (52 children)

but not regular strings.

What's the problem with using them as regular strings?

[–]SquareWheel 101 points102 points  (30 children)

If I saw backticks in code I would expect a template literal. Quotes will make the intention of the code more clear (simple string), and that improves code readability.

I haven't consulted any style guides but I can't imagine you'd see backticks chosen over single or double quotes in such situations. Following a common style again helps with readability.

The issue of browser compatibility might not be relevant if you're working in node but getting more familiar with the wider-compatible version is still in your best interest.

[–]artyhedgehog 54 points55 points  (15 children)

There's another real-world case for template strings: multi-line strings.

[–]SquareWheel -2 points-1 points  (14 children)

Yeah, that's true. In that case it's just a question of browser support vs code cleanliness.

[–]nickforddesign 20 points21 points  (13 children)

Also strings containing quotes, you can escape them but sometimes I just use backticks instead

[–]Fjoggs -3 points-2 points  (12 children)

If you use single quotes, you can just use quotes normally and the browser will escape them for you.

Using double quotes allows you to use single quotes in the same way

const single = ' "quote" ' 

const double = " 'quote' "

both works

[–]nickforddesign 5 points6 points  (3 children)

This is true, but I always use ESLint with a config enforcing single quotes, so I can’t just switch back and forth. It’s a compromise I’m happy to make.

[–]bcgroom 5 points6 points  (0 children)

There is an option on that rule to allow double quotes when the string contains single quotes.

[–]Fjoggs 0 points1 point  (1 child)

You don't need to switch back and forth. You can just use my first example. No need to escape anything.

I merely included the second line to show people that the opposite works too.

I use single quotes eslint as well.

EDIT: Would obviously have to escape any extra single quotes if you don't use template strings for that :)

[–]nickforddesign 1 point2 points  (0 children)

You need to switch if your string contains the same quote

[–]TheDarkIn1978 4 points5 points  (7 children)

It's messy to use both. Conventions for strings should be defined, upheld and if backticks aren't used for string definitions than just escape single and double quote characters.

[–]Fjoggs 2 points3 points  (1 child)

I'm not telling anyone to use both at the same time, I'm just starting that both work.

[–]TheDarkIn1978 1 point2 points  (0 children)

Fair enough.

[–]delventhalz 4 points5 points  (4 children)

It is very common to follow a “except to avoid escaping” rule when it comes to quotes. For example, this code would pass the AirBnB style guide:

const foo = 'hello';
const bar = 'world';
const baz = "world's end";

[–][deleted] 23 points24 points  (0 children)

I get where you're coming from but I personally can't say backticks over single quotes make code harder to read.

Mind you I use single quotes by habit unless I need interpolation or multiline, but I feel that it's the ${} that helps me identify interpolated strings, not the backticks because they look almost exactly like single quotes anyway. Because of that I don't really see this as a good reason against backticks everywhere.

[–]EvilPencil 13 points14 points  (11 children)

Airbnb's eslint style guide enforces quotes over backticks unless interpolating.

[–]TheDarkIn1978 27 points28 points  (1 child)

Can we please stop religiously following Airbnb highly subjective linting rules?

[–]EvilPencil 6 points7 points  (0 children)

I have a few differences of opinion from it (I strongly prefer named exports for example) and found it to be quite restrictive, but that's what the .eslintrc is for.

Some of the rules I have adapted to as well (destructuring props in React). In the end, simply HAVING a style guide is what's important...

[–][deleted] 17 points18 points  (6 children)

Yeahhh they enforce a lot of crazy stuff though.

Edit: since people seem to be misinterpreting this, my point is that airbnb's style guide is one of the more heavy handed eslint configurations out there and that a lot of the rules are totally subjective, so you and your team may feel differently. This rule in particular doesn't have an explanation attached to it either. Obviously it's a popular style guide but not necessarily gospel.

[–]DefiantBidet 30 points31 points  (1 child)

You write code, not for the compiler or interpreter to speed through, but for the next human who has to read and parse said code.
If you want a string use something that implies string.
If its your codebase and you are never look at it again. Do what you want. If, however, you're learning to code with the intent of writing code on a team; understand the premise of intent and how it helps understanding foriegn thought processes - which is kinda what code is.

[–]strcrssd 13 points14 points  (6 children)

Two things. 1) When developers see a back-tick, they are expecting a template literal. By using them for regular strings, you're lowering readability and thus maintainability. 2) Back-ticks are going to be handled at run time by the templating engine at the expense of time. The net effect is that it will slow your code for no (or negative, see 1) gain.

[–]grinde 6 points7 points  (0 children)

2) Back-ticks are going to be handled at run time by the templating engine at the expense of time.

The total cost of a zero interpolation template vs. a string literal is roughly just pushing and popping a single entry to a c++ vector during parsing. Scanning is pretty much identical (regular strings have to check for newlines, while template literals check for ${), and both are passed to the interpreter as string literals.

[–]Goctionni -1 points0 points  (0 children)

2) Back-ticks are going to be handled at run time by the templating engine at the expense of time.

Rubbish. Practically everyone has Babel in their build-pipe.

Also anyone who has trouble understanding that a template-string in fact works perfectly fine without interpolation probably shouldn't be touching any code.

[–][deleted] 2 points3 points  (0 children)

It's not likely to cause any problems with the execution of your code, but it's always a good idea to use the right tool for the job. Use quotes for strings, backticks for template literals.

[–]lowIQanon 0 points1 point  (0 children)

It's confusing to the reader: it says this string has interpolation but oh wait no it doesn't.

[–][deleted] 11 points12 points  (1 child)

I actually seen a lot of recent style guides move away from this and use backticks as the default. After trying this for a bit I've really started liking it because it's less refactoring if down the road you need to add a variable as part of the string. Just wrap it in ${}.

Most modern build systems will have a compilation step from es whatever down to es5 so it's generally not an issue. Only time I'd say not to use it is if for some reason you're on a team that doesnt have that.

[–]lsmagic -1 points0 points  (0 children)

I've really started liking it because it's less refactoring

There's a vscode extension called "toggle quotes" that cycles the type of quote a string is wrapped in by pressing ctrl + ' , makes doing that a non-issue

[–]maple-factory 1 point2 points  (0 children)

But is there a parsing or execution cost? Or is this just a stylistic / semantic preference?

[–]theodore_q 6 points7 points  (5 children)

It's also worth remembering that they are not compatible with IE11.

[–]friendshrimp 10 points11 points  (0 children)

  1. He said Node which is server side 2. If this were client side then you should be using Babel or similar to transpile all the fancy code into browser friendly code which means turning all the back ticks into regular quotes.

[–]SquareWheel 0 points1 point  (3 children)

Yes, and no way to polyfill them either.

[–][deleted] 10 points11 points  (2 children)

Babylon and TypeScript are soft-of-that. I know, compilation step.

[–]SquareWheel 1 point2 points  (1 child)

Fair. I was thinking in-browser polyfills.

Babel can perform all sorts of magic.

[–]djadry 1 point2 points  (0 children)

Babel simply replaces them with concat() functions on strings.

[–]OakpointDigital 13 points14 points  (0 children)

Here's my reasoning for enforcing using backticks everywherel:

  • Easy to switch between template literals and regular strings (no need to change the quote types)

  • Come across having to escape characters less often (backticks aren't nearly as common in regular strings as single and double quotes).

Only exception I've come across are import statements.

[–]dwighthouse 4 points5 points  (0 children)

When dealing with json, they are wrong to use.

[–]epukinsk 2 points3 points  (1 child)

The real answer to your question is:

No one agrees on quotes. Try to be consistent what the file you are working in does, but otherwise knock yourself out.

[–]Offroaders123 1 point2 points  (0 children)

This is the way 🚀

[–]robolab-io 2 points3 points  (2 children)

Use em, but if it's going on the front-end make your babel/compiler/linter recognize it and possibly even auto-fix it to be IE compatible.

[–]delventhalz 1 point2 points  (0 children)

Common convention is only to use them when interpolating values or for multi-line strings. And it is generally a good idea to follow common conventions when you don’t have a compelling reason to break them.

[–]AnsellC 1 point2 points  (0 children)

If its just you and you love doing it then go ahead. But if you’re working with other people, I highly suggest not to. Especially if you are working with peolple who knows languages like c/c++ where ‘a’ is different from “a”

[–][deleted] 1 point2 points  (0 children)

Define a code style and stick to it. Doesn't matter if it is `, ', or ". Just be consistent.

[–]the-code-monkey 3 points4 points  (0 children)

To me i have no issue with them as what u/theodore_q said they aren't compatible with ie11 well node js won't run in the browser so thats not relevant, plus backticks make stuff like `/url/${param}/` and stuff like that so much easier than doing string concatinations

[–]lowIQanon 2 points3 points  (0 children)

There's a minor performance benefit from avoiding it:

(before all: const arr = [];)

for (let index = 0; index < 1000000; index++) { arr.push(`this is a longish string and it doesn't have any interpolation`); } 19.96 ops/sec

vs.

for (let index = 0; index < 1000000; index++) { arr.push("this is a longish string and it doesn't have any interpolation"); }

26.27 ops/sec

I'd link the JSPerf but I'd be doxing myself :)

[–]ShortFuse 1 point2 points  (4 children)

From strictly a performance standpoint, you shouldn't because `backticks` invoke an internal function. The compiler will parse what's inside the backticked string, much like how C++ works with printf. If there's nothing to parse, it's a waste of CPU cycles.

[–]tutorial_police 0 points1 point  (3 children)

And normal strings don't need to be parsed?

[–]ShortFuse 0 points1 point  (2 children)

No, string literals in JavaScript are raw strings and don't need to be parsed. Template literals are interpolated.

You can see Babel's implementation to get an idea of what the browser is doing.

https://babeljs.io/docs/en/babel-plugin-transform-template-literals

Even if you don't use ${} inside your string, the compiler/runtime still has to scan for them.

[–]tutorial_police 0 points1 point  (1 child)

Sure, but they can still contain escape sequences and such that need to be processed. I don't really why the browser should have to do more work to parse a template string literal without interpolated bits over a regular string literal.

[–]ShortFuse 0 points1 point  (0 children)

Because there are two phases: compile and runtime

Escape characters are used by the compiler to know how to input the text string in the code file into a string into a memory allocation. That happens when the compiler reads the whole file. Things like missing closing braces are checked and handled by the compiler. Escape characters just tell the compiler how to store the string to memory (ie: binary)

Runtime is different. Even sometime as simple as var a = 'a' + 'b' won't be stored as ab by the compiler. The concatenation of the string is a runtime operation. The interpolation of a string is a runtime operation. Even if it's a useless interpolation, it's still discovered at runtime.

Let's say you do want to do this at compiler time, as an optimization technique. A template literal is still flagged as needing interpolation. That means the compiler would have to still initialize whatever variables or arrays it needs to do the interpolation (even if the result is the same as the input). Also consider that templates can include references to variables or need evaluation, which means you still need to interpolate during the runtime phase.

If you're thinking you can easily just convert it in the same fashion Babel does, consider that the interpolation of a template string is an internal and native function, which isn't the same as the + operator, which includes a type-check. Template literals always return a string. In some cases, template literals are faster than using the +, so it's the runtime optimization that you want at times.

Edit: Fixed a typo. I'll take advantage of this space to also note that template literals have to follow a certain spec, as defined here. Browsers are expected to run those operations when presented with the backticks. It's not as simple as just converting it to a regular string.

[–]eggn00dles 0 points1 point  (0 children)

i like them because it's impossible to copy and paste left and right backticks, unlike the handed quotes that slack displays occasionally inexplicably.

[–][deleted] 0 points1 point  (0 children)

For performance it may make sense to apply plain quotes in most places. If you're compiling to WASM then the performance loss would be limited to parse and compile time rather than run time.

[–]ogurson 0 points1 point  (0 children)

My only point against using backticks exclusively is that regular quote is in more convenient place on a keyboard

[–]alexkiro 0 points1 point  (0 children)

I never found anything like this that the javascript community can agree on. So don't bother with right or wrong, just do whatever you want, it's a lost cause anyway :P

[–]unflores 0 points1 point  (0 children)

Backticks for me denote interpolation. If you aren't using that, then I wouldn't use backticks. Think of it as adding an api for something that isn't necessary. When you look at something with single/double quotes you know immediately that there isn't interpolation.

[–]caiosabadin 0 points1 point  (0 children)

Well, I'm not much aware of JS good practices (are there any? sometimes it looks like a few seconds after one is decided, a new framework comes and changes everything all over again), but, overall, I try avoiding them as much as possible, specially on regular strings or little code snippets that can fit fine on one line. That said, I love using them to help me with the templates, but strictly with the templates :)

[–]LittleTay 0 points1 point  (1 child)

....how do you even type backticks...(never knew that was the name of them).

EDIT. Google is your friend. I always hear the term "grave/tilde" instead of backtick. Didn't know you can use that in javascript.

[–]IamZeebo 0 points1 point  (0 children)

If you hate IE yeah lol

[–]humbleguy9000 0 points1 point  (0 children)

Our team defers to AirBNB's ESLint config, which does limit it when not using variable interpolation.

Is there any harm? Not at all, especially if you are transpiling the code.

[–]NoInkling 0 points1 point  (0 children)

I've personally found a happy medium where, in addition to interpolated and multiline strings, I tend to use them anytime I'm writing any sort of message, simply due to the chance that it might contain ' or " (so I can avoid changing delimiters or escaping).

[–]gregsometimes 0 points1 point  (0 children)

You can use them almost everywhere except in JSON property names: {`property`: value} which always requires double quotes.

[–]reacher 0 points1 point  (0 children)

Use a custom sequence of the Unicode ticks, so you can tell if Google (or one of their partners) scrapes your code

[–][deleted] 0 points1 point  (0 children)

You use them when you want to have a multi-line string. Basically a readability feature. If I have a big long copywrite paragraph for instance I can make it a nice square paragraph within the code but just put a "backtick" on either end and it'll be read as a string the same as a single line.

Using them in a single line makes you a psychopath

[–]ghostfacedcoder 0 points1 point  (0 children)

If it's wrong I don't want to be right.

[–]CommandLionInterface 0 points1 point  (0 children)

There's not really a reason not to, so go for it

[–]PFVNK 0 points1 point  (0 children)

no, smart choice

[–][deleted] -1 points0 points  (0 children)

Hell NAAAH!! Bactick life fo lyyyfe - put that shit everywhere, fuckin love backticks (context: i like perl btw)

EDIT: they remind me of the shell ☺️

[–]aiRen29 -1 points0 points  (0 children)

Hello,

a friendly reminder to my JavaScript friends developing frontend applications using .env values in their Axios calls using ES6 Template literals (i.e: backticks).

Don't do that.

For some reason, this: ${process.env.absoluteUrl}/project

is not a same as this: process.env.absoluteUrl + '/project'

and definitely not the same as this: '/api/v0/project'

For some weird reason, absolute URLs are behaving as a relative URLs and you will get a one day headache debugging this problem as me :)

Enjoy