如何强制Google Closure编译器在编译后的JS代码中保留"use strict";?

34

如果你正在使用模块模式,并且有这样的代码:

(function () {
   "use strict";
   // this function is strict...
}());

如果使用Google Closure Compiler编译代码,"use strict";指令将不会出现在编译后的文件中。

那么如何防止Closure Compiler删除ES5/strict指令呢?

(请注意,我不想使用另一种强制启用ES5/strict模式的方法,即在编译后的文件的第一行简单地添加 "use strict";。我想要使用模块模式,如这里所述。)

5个回答

53

有没有相应的注解? - ryanve
从最初的调查来看,似乎在这种模式下,闭包编译器不会从连接的文件中剥离不必要的"use strict"语句... 值得注意。 - The Trav
如果还没有的话,它似乎还会在顶部添加 'use strict';。不错! - Kyle Falconer
1
在我的情况下,只需添加 --language_out=ECMASCRIPT5_STRICT,最终的代码压缩中就会包含 'use strict'; - IvanRF

11

虽然这个答案不是很好,但据我所知,这是闭包编译器已知的一个问题或“特性”(取决于你的观点)。 这里是一些相关问题的部分解释。 其中提到的一些问题是,当合并多个文件时,没有办法保留文件级别的严格模式声明,并且编译器的函数内联功能会破坏函数级别的严格模式声明的范围。 由于在编译后的代码中,“use strict”声明的行为是不可预测/错误的(可能会在将严格模式错误应用于非严格代码时破坏程序),因此编译器像任何其他死代码一样删除它们。

似乎曾经有一个想法,在编译器中完全实现ECMAScript 5严格模式检查(在这种情况下,从编译代码中删除它将没有任何缺点),但目前还没有实现。

使用SIMPLE_OPTIMIZATIONS模式进行编译而不是ADVANCED_OPTIMIZATIONS将禁用死代码删除,但我认为您已经知道了这一点。


3
更新:Ben Challenor的下方答案似乎是新的“正确”答案。 - Robert Martin

8

危险。高级模式下的Closure Compiler不兼容严格模式,这意味着编译器将根据ECMAScript 262 rev 3规则重写代码。某些规则在严格模式下会发生更改(例如匿名函数中的"this"绑定、作用域解析等),如果Closure Compiler由于错误的语言假设而重写代码,则会导致代码破坏。

简短的答案(也是Closure Compiler的官方答案)是:不要这样做。

如果您真的只想在那里加入一个"use strict"字符串,请尝试:

eval('"use strict";');

1
您可以使用编译器的输出包装器来创建模块包装器,并在其中包含"use strict"指令。

0

严格模式对于调试非常有用,但在被每个主要浏览器采用之前并没有太多其他用途。当 Closure Compiler移除该标记时,它的有用时代已经结束了。我相信他们会更新编译器以允许在那个功能实际上有用之前保留该标记。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接