4

Since a few week, I omit semicolons in my JavaScript files. I realized today it may cause issues if the file is minifyed.

I read the following ressources:

There are two points of view:

  • If a tool processes a javascript file that worked and turned it into a javascript file that doesn't work, that tool doesn't hold true to its promise of “without changing its functionality”.
  • Since omiting semicolons prevent the file from being minifyed, semicolons must be added.

What is the best option in the general case? I mean by "general case" that the source code should be generic and minifyed by any minifyer.

Fifi
  • 3,360
  • 2
  • 27
  • 53
  • 6
    Missing semicolons can cause issues even if your code is *not* minified. It's always a good idea to use semicolons. –  Jan 17 '20 at 19:32
  • 3
    I'd expect a good minifier to not care whether you have semicolons or not. They'd just produce minified code that works the same as before. If a minifier *doesn't* do that, then I'd consider it not a good minifier and avoid it - who knows what else it will mess up. – VLAZ Jan 17 '20 at 19:33
  • 2
    @VLAZ I think the issue isn't in the minifier itself, but the interpreter which incorrectly guesses where statements end. Using semicolons means no guessing, which means no bad guesses. –  Jan 17 '20 at 19:33
  • 4
    @Amy but an interpreter doesn't *guess*. It follows the very strict rules for ASI laid down from the very first version of the ES specs. Any code will be completely predictably executed from any specs conforming interpreter. And any minfier that doesn't produce ASI equivalent code is, by definition, non-specs conforming. If the code misbehaves due to the absence of semicolons, that's a developer error. Assuming the code written is *correct*, then if a minifier should makes it incorrect, that minifier wrong and to be avoided. Yes semicolons are a good idea but adding them *for tooling* is bad. – VLAZ Jan 17 '20 at 19:39
  • 1
    @Amy let's put it that way the code `if (cond) { doSomething() }` is convertible to `if(cond) doSomething()` the two are equivalent. However, if you apply the same transformation to `if(cond) { doSomething(); doSomethingElse() }` and remove the curly brackets, then the code becomes wrong. Using a tool that does it is *not a good idea* no matter whether feel about curly brackets should be there or not for single line statements. – VLAZ Jan 17 '20 at 19:44
  • @VLAZ Using `return { a: 3 }`, where the `return` is on its own line and the object is on the next line, then ASI will kick in and insert a semicolon after the `return` statement. That wasn't what was intended, though. Using semicolons avoids situations like this. –  Jan 17 '20 at 19:44
  • always use semicolons, and be safe that not there a semicolon after statements, because it's interpreted an empty statement, However, it's not a syntax error – Hossein Shourabi Jan 17 '20 at 19:45
  • @Amy But if the `return` were on its own line in the original code, not even the original code would run correctly on any spec-conforming JS interpreter. If the original code doesn't run correctly, the minified code shouldn't either. – Klaycon Jan 17 '20 at 19:47
  • However I fully agree that it's always a good idea to use semicolons – Klaycon Jan 17 '20 at 19:47
  • @Klaycon My original point is that it isn't the minifier that needs these semicolons, and even unminified code can behave unexpectedly without them. –  Jan 17 '20 at 19:47
  • @Amy that is still as per the specs. Computers do what we tell them to, not what we mean. That's what I am trying to convey - it's the *programmer* who failed to express themselves correctly, it's not an unpredictable error related to how their code was read. A minifier would *still* produce equivalent code and might even drop a dead expression. A minifier would, therefore, *not* change the semantics of the code, just how they are expressed. – VLAZ Jan 17 '20 at 19:48
  • @VLAZ I think you're reading too much into my use of the word "guess". The interpreter is trying to determine what the programmer meant and made a bad call. Yes, its deterministic, and yes its behaving exactly according to the specs. That's really beside the point though. Using semicolons avoids this situation entirely, and using semicolons is the *programmers* call. ASI is a bad feature that turns JS into a [Pit of Failure](https://blog.codinghorror.com/falling-into-the-pit-of-success/). –  Jan 17 '20 at 19:50
  • 2
    @Amy the question is whether or not semicolons should be used for *tooling*. Again, I completely agree that semicolons are good. However, using them *to satisfy tooling* is completely the wrong argument for their usage. – VLAZ Jan 17 '20 at 19:52

1 Answers1

3

It shouldn't cause problems, as long as the minifier does not have bugs within it.

This is because JavaScript code without semicolons is perfectly valid, parseable JavaScript.

And this can be accurately and reproducibly minified.

No "guesswork" will be involved - only a well-defined, deterministic parsing algorithm, based on the specification.

Bugs have previously been identified in minifiers related to ASI.

So depending on the maturity of the minifier, there might be an increased risk of hitting such a bug.

That said, bugs have previously been found in minifiers unrelated to ASI too, so there will always be a risk that your minifier introduces a problem, regardless of whether you use semicolons or not.

Given all this, and the high quality and maturity of JavaScript minifiers, I would follow the coding style that makes your team happiest.

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • 1
    Note that the question specifies the source code should be minified by *any minifier* , so a definitive "No" answer should specify that it uses a definition of minifier that excludes non-spec-conforming minifiers – Klaycon Jan 17 '20 at 19:43
  • @Klaycon I think "any minifier" is too broad. I can write a minifier that simpy drops all whitespace from the code thus making it smaller. It's also going to be completely useless and would produce a syntax error for almost all code you run through it. Should we, therefore, write code that can be minified though it? We could - `var a = 1` cannot exist in it but `a = 1` is minifiable. – VLAZ Jan 17 '20 at 19:50