The question 'How does Google Closure Compiler handle quotes (string literals)?' could also be re-phrased like:
Note 1: this question is not about why Closure (or some other minifiers) have chosen to prefer double quotes (as is asked here and here).
Note 2: this question is not about single vs double quote discussions, however some understanding what GCC does to our code (and why) is rather useful!
It is often stated that (or asked why) Google Closure Compiler (GCC) replaces single quotes with double-quotes (even when the compilation_level
is set to WHITESPACE_ONLY
!!!):
example xmp_1.js:
alert('Hello world!'); // output: alert("Hello world!");
However... this is only half of 'the truth', because:
example xmp_2.js:
alert('Hello "world"!'); // output: alert('Hello "world"!');
// *NOT*: alert("Hello \"world\"!");
GCC is essentially a 'your raw javascript' to 'smaller (and more efficient) javascript' translator: so it does not 'blindly' replace single quotes with double quotes, but tries to choose an 'optimal quote-character' (after all.. one of the primary goals is to 'mini-fy' the script).
From the source-code (CompilerOptions.java) and this issue-report one can learn that:
If the string contains more single quotes than double quotes then the compiler will wrap the string using double quotes and vice versa.
If the string contains no quotes or an equal number of single and double quotes, then the compiler will default to using double quotes.
Like this example xmp_3.js:
alert('Hello "w\'orld"!'); // output: alert('Hello "w\'orld"!');
alert('Hello "w\'o\'rld"!'); // alert("Hello \"w'o'rld\"!");
Note how the above xmp_3 results in a 'mixed' output that uses both '
and "
as outer quotation: the optimal choice followed by the default (when it didn't matter).
As it turned out there are some serious legitimate real-world cases where defaulting to single-quotes would have been better. As explained in the issue 836 (from Oct 8, 2012) referenced above:
The FT web app (app.ft.com) and the Economist app for Playbook deliver JavaScript updates to the client along with other resources by transmitting them as part of a JSON-encoded object. JSON uses double quotes natively, so all the double quotes in the compiled JavaScript need to be escaped. This inflates the size of the FT web app's JS by about 20kB when transmitting a large update.
The reporter of the issue came with a gift: a patch that added the option prefer_single_quotes
to change the default quote-character from double quote to single quote.
This issue was taken seriously enough that project member Santos considered changing the default double quote to single quote ('and see if anybody complains').. TWICE (also after the reporter/patch-contributer stated that he implemented it as an option so that it wouldn't have any backward-compatibility consequences since 'someone might be relying on strings being output with double quotes for some bizarre reason').
However, about one week later the patch was accepted (r2258), another week later reworked (r2257) and on Oct 30, 2012 Santos reported back that the option could now be enabled with:
--formatting=SINGLE_QUOTES
(so a third option besides PRETTY_PRINT
and PRINT_INPUT_DELIMITER
for the formatting
-key).
(Note: in the current source-code one can currently still find numerous references to 'prefer_single_quotes' as well.)
Usage:
If you (download and) use the (local java) application:
java -jar compiler.jar --js xmp_1.js --formatting SINGLE_QUOTES
and you will see that: alert('Hello world!');
now compiles to alert('Hello world!');
However, at this time of writing, the Compiler Service API and UI (that most probably uses the API) located at http://closure-compiler.appspot.com, do not accept this third (new, although a year in existence) formatting-option: SINGLE_QUOTES
and will throw an error:
17: Unknown formatting option single_quotes.
After digging (again) through the source, it seems (I'm not a Java-expert) that this is because jscomp/webservice/common/Protocol.java only accepts the older PRETTY_PRINT
and PRINT_INPUT_DELIMITER
* All the possible values for the FORMATTING key.
*/
public static enum FormattingKey implements ProtocolEnum {
PRETTY_PRINT("pretty_print"),
PRINT_INPUT_DELIMITER("print_input_delimiter"),
;
I will update this answer should this option become available in the API and/or UI.
Hope this helps and saves someone some time, since the only documentation and reference google can find about SINGLE_QUOTES
is currently in this one issue 836 and some comments in the source. Now it has some explanation on SO (where I'd expect it).