5

I'm trying to retrofit/fix lots of legacy web code and unfortunately most of it is poorly formatted JavaScript. I'm looking for a batch/scriptable utility that can fix JavaScript that is missing simicolons at the end of executable statements.

I've tried the beautify-cl.js script with Rhino but that does not does not add semicolons. In addition, I have tried JSTidy thinking I could modify it to be scriptable, but it strips all comments. Considering we have something like 2000-3000 files, any solution has to be scriptable.

The following topics were referenced, however none of the solutions were sufficient for various reasons: Javascript Beautifier - Doesn't handle semicolon Best source code formatter for Javascript? - Not scriptable

Any ideas/solutions? Thanks in advance.

Community
  • 1
  • 1
Paul Kuykendall
  • 3,167
  • 1
  • 20
  • 17
  • Did you try http://www.jslint.com/? It’s not a beautifier but the best quality checker tool. The rest would be manual work. – Gumbo Jun 25 '09 at 17:40
  • Yes, it is fine for finding the problems. Unfortunately, going through 3000 files and manually adding semicolons at the end of each executable line is beyond tedious. Many of the files are more than 50k. – Paul Kuykendall Jun 25 '09 at 17:44
  • Do you have any special reasons for adding semicolons (like using a special JS packer)? Otherwise omitting the semicolon is still conforming to the spec. – Boldewyn Jun 25 '09 at 17:57

6 Answers6

2

I've found a winning combination in js-beautify and Google's Closure Linter:

# legacy.js is your poorly formatted JavaScript file, and will be modified in-place
js-beautify -s 2 -n -b end-expand -x -r legacy.js && fixjsstyle legacy.js

Explanation of js-beautify options:

  • -s 2: indent with two spaces
  • -n: ensure newline at end of file
  • -b end-expand: puts { braces at the end of the line, but always gives } braces their own line.
  • -x: unescape \xNN-escaped characters in strings
  • -r: make changes in-place

fixjsstyle, which is installed with the Closure Linter suite, makes changes in-place by default.

This pipeline retains comments (!), indents everything (mostly) how I like, adds semicolons where appropriate, and even changes double quotes to single quotes where feasible. Both commands can be given a list of files (e.g., **/*.js), instead of just one.

To install the required packages on Mac OS X:

npm install -g js-beautify
brew install closure-linter
chbrown
  • 11,865
  • 2
  • 52
  • 60
1

Obviously you'll need to do this if you want to minify the files on deployment. Missing semicolons are probably the #1 reason JS files don't minify properly, so I understand your motivation.

Write a little Python (or whatever) script to run the file through jslint, then use the output from jslint to see which lines need semicolons, then spin through the js source and add them.

I think you can be fairly fearless here, because JavaScript implicitly adds the semicolons anyway.


Update: This set of tools may be what you are looking for. The "format" tab offers missing semicolon insertion.

Nosredna
  • 83,000
  • 15
  • 95
  • 122
  • right, and who's going to ensure that it all works exactly like it did before? – Allen Rice Jun 25 '09 at 18:02
  • That's a risk. But I think his odds are good. I have not had JSLint tell me to add a semicolon when I shouldn't. I've seen plenty of people take jslint's semicolon suggestions mindlessly anyway. He'd be wasting a lot of time to go through by hand with jslint if there is a business reason to minify. And he'd be accepting jslint's semicolon suggestions mindlessly anyway, with that many files. – Nosredna Jun 25 '09 at 18:07
  • If he has that many big files, and it's sloppily written, it's full of bugs anyway. He might as well be debugging code after it's been through a bit of jslint semicolon sanity checking. – Nosredna Jun 25 '09 at 18:11
  • I have no problem with semi colon insertion 1 file at a time, as he's working on them. That makes sense and I stated that in my answer. 1 big huge batch seems silly though, IMO. A typical minifier should be able to get the file size down to a somewhat reasonable size as the code is. – Allen Rice Jun 25 '09 at 18:15
1

If you use JavaScript Utlity V2 at http://jsutility.pjoneil.net and use the formatting function, it will automatically replace missing semicolons.

In addition, if you use the compaction function, it will also replace missing semicolons so that the compaction will not cause any errors.

Pat
  • 145
  • 2
  • 11
0

You shouldn't be worried about doing a mass update on a lot of legacy code for the sole purpose of inserting semi colons. That's a classic case of "doing it wrong".

How would you test the results? How would you ensure no "functionality" (as a side effect of a bug caused by a semi colon being missing) isn't lost?

What do you think adding semi colons to all these files will get you? Beside larger files (I'm not knocking the use of semicolons) and massive amounts of untested code changes?

As gumbo said, use jslint. I would use it on the files as you edit them in your day to day work. As you edit these files, presumably you will be testing changes to the file at that time. That would be the most ideal time to go crazy with semi colon insertion.

Also, if you're concerned about keeping 2000-3000 legacy javascript files alive and supported, you've got far bigger problems than semi colons

Allen Rice
  • 19,068
  • 14
  • 83
  • 115
  • If there's good coverage with unit tests, you could pull it off. But chances are, if it's that poorly formatted to begin with, there aren't any unit tests. – Matthew Groves Jun 25 '09 at 17:53
  • Exactly, mgroves. Obviously significant code coverage allows for fearless refactoring, but I highly doubt this is the case in this situation :) – Allen Rice Jun 25 '09 at 17:55
  • I agree. It's worthwhile to use jslint (or a similar tool) whenever changing a file for another reason. But skip the huge mass migration. – Matthew Flaschen Jun 25 '09 at 17:56
  • The main issue is so that we can do things like minify more safely. In addition, many of the tools out there assume that the code is more well-formed than it currently is. We've got regression testing to verify things so that isn't as much of an issue. Plus now is actually an excellent time for us to do a "big bang" change, as other required changes necessitate a full regression. Those other changes were relatively easy, but automatable. – Paul Kuykendall Jun 25 '09 at 18:01
  • For fun, I'm going to disagree with you guys, because JavaScript implicitly adds the semicolons anyway. I think it's a reasonably safe refactor. John Candy in Stripes: "If it were me, I'd bet everything. But that's me. I'm an aggressive gambler. Mr. Vegas. Come on. Go for it." – Nosredna Jun 25 '09 at 18:03
  • What kind of regression testing? Automated? What % coverage? You just spent a good deal convincing everyone that this would be a monumental task to add semi colons due to size and scope but now you've got regression testing down pat, no worries? – Allen Rice Jun 25 '09 at 18:05
0

If http://jsutility.pjoneil.net is throwing too much errors (and be unable to format it), you may try to compress it with: http://refresh-sf.com/yui/ (which will add missing semicolons) and then go back to pjoneil.net formatter to obtain the pretty code with semicolons.

lepe
  • 24,677
  • 9
  • 99
  • 108
0

If you are using Visual Studio Code then Prettier Formatter is the way to go: https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

You simply install it and then on the keyboard shortcut to Format Document, the js file is reformatted but also any missing semicolons are automatically filled.

Enjoy!

George Pligoropoulos
  • 2,919
  • 3
  • 33
  • 65