2

问题“Google Closure Compiler 如何处理引号(字符串文字)?” 也可以改写为:

  • 为什么 Closure 用双引号替换/交换单引号?
  • Closure 如何决定使用哪种引用格式/样式?
  • (如何)我可以改变这个(默认)行为吗?

注1:这个问题不是关于为什么闭包(或其他一些缩小器)选择更喜欢双引号(如herehere所问)。

注意 2:这个问题不是关于单引号和双引号的讨论,但是了解 GCC 对我们的代码做了什么(以及为什么)是相当有用的!

4

1 回答 1

5

人们经常说(或问为什么)G oogle C losure C ompiler (GCC) 用双引号替换单引号(即使compilation_level设置为WHITESPACE_ONLY!!!):

示例xmp_1.js:

alert('Hello world!');           // output: alert("Hello world!");

然而......这只是“真相”的一半,因为:

示例xmp_2.js:

alert('Hello "world"!');         // output: alert('Hello "world"!');
                                 //  *NOT*: alert("Hello \"world\"!");

GCC 本质上是一个“你的原始 javascript”“更小(更高效)的 javascript”的翻译器:所以它不会“盲目地”用双引号替换单引号,而是尝试选择一个“最佳引号字符”(毕竟。 . 主要目标之一是“缩小”脚本)。

从源代码(CompilerOptions.java)和这个问题报告中可以了解到:

如果字符串包含的单引号多于双引号,则编译器将使用双引号包裹字符串,反之亦然。
如果字符串不包含引号或包含相同数量的单引号和双引号,那么编译器将默认使用双引号

像这个例子xmp_3.js:

alert('Hello "w\'orld"!');       // output: alert('Hello "w\'orld"!');
alert('Hello "w\'o\'rld"!');     //         alert("Hello \"w'o'rld\"!");

请注意上面的 xmp_3 如何导致使用'"作为外部引号的“混合”输出:最佳选择后跟默认值(当它无关紧要时)。

如何将默认双引号更改/覆盖为单引号?

事实证明,在一些严重的真实案例中,默认使用单引号会更好。正如上面引用的问题 836(从 2012 年 10 月 8 日起)中所解释的:

FT Web 应用程序 (app.ft.com) 和适用于 Playbook 的 Economist 应用程序通过将 JavaScript 更新与其他资源一起作为 JSON 编码对象的一部分传输给客户端。JSON 原生使用双引号,因此编译后的 JavaScript 中的所有双引号都需要转义。在传输大更新时,这会使 FT 网络应用程序的 JS 的大小膨胀约 20kB。

问题的记者带来了一份礼物:一个补丁,添加了prefer_single_quotes将默认引号字符从双引号更改为单引号的选项。

这个问题被认真对待,以至于项目成员 Santos考虑将默认的双引号更改为单引号('看看是否有人抱怨').. TWICE(也在记者/补丁贡献者声明他将其作为一个选项实施之后,以便它不会产生任何向后兼容的后果,因为“出于某种奇怪的原因,有人可能会依赖用双引号输出的字符串”)。

然而,大约一周后补丁被接受(r2258),又一周后重新设计(r2257),2012 年 10 月 30 日,Santos 报告说现在可以启用该选项:(所以除了-key之外还有 第三个选项)。 (注意:在当前的源代码中,目前仍然可以找到大量对“prefer_single_quotes”的引用。)
--formatting=SINGLE_QUOTES
PRETTY_PRINTPRINT_INPUT_DELIMITERformatting

用法:
如果您(下载并)使用(本地 java)应用程序:

java -jar compiler.jar --js xmp_1.js --formatting SINGLE_QUOTES 你会看到:alert('Hello world!');现在编译为alert('Hello world!');

但是,在撰写本文时,位于http://closure-compiler.appspot.com的编译器服务 API 和 UI(很可能使用该 API)不接受这第三个(新的,虽然存在一年)格式化选项:SINGLE_QUOTES并且会抛出错误:
17: Unknown formatting option single_quotes.

在(再次)挖掘源代码之后,似乎(我不是 Java 专家)这是因为jscomp/webservice/common/Protocol.java只接受旧的PRETTY_PRINTPRINT_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"),
  ;

如果此选项在 API 和/或 UI 中可用,我将更新此答案。

希望这有助于并节省一些时间,因为谷歌可以找到的唯一文档和参考SINGLE_QUOTES目前在这一期 836 和源代码中的一些评论中。现在它对SO有一些解释(我期望它)。

于 2013-11-09T10:24:05.497 回答