Why would you expect that to be true in JavaScript any more than other semicolon-optional languages like Ruby and Python?
You just write your parser to accept both line endings (that meet certain conditions) and semicolons as statement terminators. Going through and literally inserting semicolons shouldn't be necessary.
Python is somewhat different, in that a newline is simply a statement separator. Semicolons aren't inserted, as far as I know, they're simply an alternate statement separator.
Python does make some exceptions, in that newlines within balanced paratheses and brackets are not treated as statement separators. But outside of that, this is what they mean.
As an example of the difference, consider the following JS:
if
(0)
statement()
This is legal JS. Now consider the roughly equivalent Python:
if
0:
statement()
This is not legal python, because the newline after the "if" terminated the statement, and a bare "if" is not a legal statement.
Another example. This is legal JS:
obj
.method()
As it is parsed as a single statement in JS. However, it is not legal Python, as the newline after "obj" definitively ends the statement, and ".method()" by itself is not a legal statement.
In short, Python can always say "this newline is the end of a statement", except for some very easy-to-detect cases. JavaScript, on the other hand, parses until it encounters an error, then goes back to insert the semicolon and tries again. This implies some additional overhead. I don't imagine it's a significant amount at all, but there is at least a good reason to think that this might apply to JS but not a language like Python.
My understanding (though I'm not an expert) is that the way the JavaScript spec is written, you first try to parse a line as is, and if you encounter a parsing error in trying to do that and the line doesn't have a semicolon, then you insert a semicolon and you try again. The end result is that it's a bit different then semicolons being optional; they are instead inserted automatically to try to recover from parse errors.
You just write your parser to accept both line endings (that meet certain conditions) and semicolons as statement terminators. Going through and literally inserting semicolons shouldn't be necessary.