简体   繁体   English

使用具有高级优化的闭包编译器时,如何在 javascript 中保留全局变量?

[英]How to preserve global variables in javascript when using Closure compiler with advanced optimization?

I have my own Javascript library, which I want to minify by using Google closure compiler with Advanced optimization.我有自己的 Javascript 库,我想通过使用具有高级优化的 Google 闭包编译器来缩小它。 By looking at the docs I see how to declare functions which are used outside of the library.通过查看文档,我了解了如何声明在库之外使用的函数。

However I couldn't find a way how to preserve global variables declared in my library.但是我找不到如何保存在我的库中声明的全局变量的方法。 Closure compiler just removes them, because it thinks they are never used.闭包编译器只是删除它们,因为它认为它们从未被使用过。 Anybody can help?有人可以帮忙吗?

Edit: example code:编辑:示例代码:

var variable_1 = true;

This is defined globally right at the beginning of my library, but it's never used in the library itself.这是在我的库开始时全局定义的,但它从未在库本身中使用。 It is used outside the library when it is included in some page.当它包含在某个页面中时,它在库之外使用。 But that Closure compiler doesn't know and thats the reason it removes these declarations.但是那个 Closure 编译器不知道,这就是它删除这些声明的原因。

The closure compiler cannot remove global variables declared as window["variable_1"] = true闭包编译器无法删除声明为window["variable_1"] = true的全局变量

I recommend you write to window directly for global variables and I also recommend you use string literals for your variable names so that closure doesn't minify it.我建议您直接写信给window以获得全局变量,我还建议您使用字符串文字作为变量名,这样闭包就不会缩小它。

Although you can refer to a "true" global variable through replacing all usage of that global variable with window["varname"] , it is usually not a good idea to "pollute" the global namespace.尽管您可以通过将全局变量的所有用法替换为window["varname"]来引用“真正的”全局变量,但“污染”全局命名空间通常不是一个好主意。 The Closure Compiler is designed to discourage you from doing this.闭包编译器旨在阻止您这样做。

CAVEAT : window["varname"] and var varname are not the same, as "window" may not always be the global object in non-browser environments.注意事项window["varname"]var varname不一样,因为在非浏览器环境中,“window”可能并不总是全局 object。 As a matter of fact, the Closure Compiler assumes that the global object and "window" are different.事实上,闭包编译器假定全局 object 和“窗口”是不同的。 For example, window["varname"] will compile to window.varname instead of var varname .例如, window["varname"]将编译为window.varname而不是var varname They are NOT the same, although in a browser they work similarly.它们并不相同,尽管在浏览器中它们的工作方式相似。

It is best to make a global namespace object, then only export that one object.最好创建一个全局命名空间 object,然后只导出一个 object。 All your "global" variables should become properties under this global namespace variable.你所有的“全局”变量都应该成为这个全局命名空间变量下的属性。 Benefits:好处:

  1. All those global variables are renamed to shorter versions所有这些全局变量都被重命名为更短的版本
  2. Inlining of constants can happen可能会发生常量内联
  3. The Closure Compiler automatically "flattens" the namespace anyway, so your code won't be any slower无论如何,闭包编译器都会自动“扁平化”命名空间,因此您的代码不会变慢
  4. Superior obfuscation高级混淆
  5. Your code also works in non-browser environments.您的代码也适用于非浏览器环境。 Remember, "window" may not always exists (eg in server-side code) and the "global object" may not always be "window"请记住,“窗口”可能并不总是存在(例如在服务器端代码中),“全局对象”可能并不总是“窗口”

If you have global variables that the user must read/set to use your library, it is also discouraged.如果您有用户必须读取/设置才能使用您的库的全局变量,也不鼓励这样做。 It is better to expose an API on the global namespace object, then expose the public API's as usual through the window object: window["myLib"]["setConfig"] = myLib.setConfig . It is better to expose an API on the global namespace object, then expose the public API's as usual through the window object: window["myLib"]["setConfig"] = myLib.setConfig .

In your case, if you have global variables used in other parts of your non-Closure-Compiled code, you have to consider:在您的情况下,如果您在非闭包编译代码的其他部分使用了全局变量,则必须考虑:

  1. Is it better to put the declaration of those variables outside of the file being compiled by Closure将这些变量的声明放在由 Closure 编译的文件之外是否更好?
  2. Why are you not putting the declaration of those variables together with the code using them为什么不将这些变量的声明与使用它们的代码放在一起
  3. Should you actually be Closure-compiling all the code instead of only a portion (it is possible? Do you use another library?)你真的应该关闭编译所有代码而不是只编译一部分(有可能吗?你使用另一个库吗?)

I've just come across this, and I have my own solution.我刚遇到这个,我有自己的解决方案。

Create you're entire library within a self-executing function, putting all the object properties as strings (at least once for each property) like so:在自动执行的 function 中创建整个库,将所有 object 属性作为字符串(每个属性至少一次),如下所示:

(function () {
    var myLibrary = {
        'myMethod' : function () {
            ...
        }
    }
    myLibrary.myMethod['propertyOfTheMethod'] = '';
}());

The usual way to make this accessible from the outside would be to put var myLibrary = before the function and return myLibrary at the end of it so that it gets assigned to a global variable.使其可以从外部访问的常用方法是将var myLibrary =放在 function 之前并在其末尾return myLibrary以便将其分配给全局变量。 But the function is executed in the global scope (because it's self-executing), so we can create a property of this using a string literal.但是 function 在全局 scope 中执行(因为它是自执行的),所以我们可以使用字符串文字创建this的属性。 So in full:完整的:

(function () {
    var myLibrary = {
        'myMethod' : function () {
            ...
        }
    }
    myLibrary.myMethod['propertyOfTheMethod'] = '';
    this['myLibrary'] = myLibrary;
}());

But, this won't work under "use strict";但是,这在"use strict"; . . The best way to get the global variable in strict mode is with var global = Function('return this')();在严格模式下获取全局变量的最佳方法是使用var global = Function('return this')(); then assign your variable to that.然后将您的变量分配给它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Javascript Closure编译器 - 导出全局变量 - Javascript Closure compiler -Exporting global variables 具有针对多个脚本的高级优化的 Google Closure Compiler - Google Closure Compiler with advanced optimization for multiple scripts 谷歌闭包编译器的高级优化没有优化一些变量 - google closure compiler's advanced optimization isn't optimizing some variables 在javascript闭包函数中保留变量 - Preserve variables in a javascript closure function Javascript优化…全局变量 - Javascript optimization…global variables 如何使闭包编译器在较大的项目中使用高级优化删除所有死代码? - How to make closure compiler to remove all dead code with advanced optimization in larger projects? 闭包编译器高级优化防止对象属性重命名 - Closure compiler Advanced Optimization prevent object property renaming 如何在 javascript 中编写一个 function ,它在调用时返回 true 或 false 作为交替而不使用闭包保留全局变量? - How to write a function in javascript which returns true or false as alternating when its invoked without keeping global variables using closure? Closure编译器(高级模式)—如何设计类? - Closure Compiler (advanced mode) — How to design classes? 如何保持JavaScript闭包的状态? - How to preserve the state of JavaScript closure?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM