如何在闭包编译器中从重命名中排除对象

Axe*_*xel 3 javascript google-closure-compiler openlayers-3

我使用closure-util 并希望有一个不重命名的对象来更改 html 中的内容。
在我的第一步中,我想将我的模块与 openlayers 3|4 一起编译。
我不熟悉 externs、export 或 api,所以我需要帮助声明闭包编译器。

片段 .html(未编译)

  olc.lon=7.11875;olc.lat=51.15345;olc.zoom=12;
Run Code Online (Sandbox Code Playgroud)

main.js 中的代码段声明将被编译

var olc = {      // namespace controls and constants
  lon         :  2.0,lat: 25.0,rota: 0,zoom: 2, // as default
  debug       :  'force'
};
window['olc'] = olc;
Run Code Online (Sandbox Code Playgroud)

现在编译后
-olc.lon重命名为olc.B,
-olc.lat重命名为olc.uj,
-olc.rota重命名为olc.mf,
-olc.zoom没有重命名,不知道为什么不是和
- olc.debug 没有重命名。

有像zoom这样的受保护词吗?
例如,我如何保护 olc.lon 免于重命名?

小智 5

避免闭包类型系统

如果您使用的是对象字面量并且不想添加更多类型信息,则可以添加'quote'属性名称。这会导致它们的值被直接使用,并防止它们被用作推断类型的一部分(如您所见,可以优化/替换)。

// namespace controls and constants
var olc = {
  'lon'  : 2.0,
  'lat'  : 25.0,
  'rota' : 0,
  'zoom' : 2, // as default
  'debug': 'force'
};
Run Code Online (Sandbox Code Playgroud)

这种优化在每个目标/项目级别上执行,而不是每个功能,使的原因zoom,并debug不会被替换可能与这里的/他们是如何与其他财产的名称在其他程序中用来做。您不应该依赖于此,它可能会发生不可预测的变化。如果您需要zoom保持原样,您必须像lat和一样引用/保护它lon

使用闭包类型系统

Closure 类型系统非常有用,像这样避免它会阻止它检测到这些值的一些潜在错误。相反,您可以在 Closure 的系统中为对象/值指定一个类型,它会进行错误检查,但不知道不重命名。

遗憾的是,有很多方法可以做到这一点,其中许多取决于 Closure Compiler 设置的微妙组合。(文档可能会告诉您使用@exports,但即使是那些在某些情况下也不起作用。)这是我最常使用的解决方案,因为它适用于大多数设置并且在概念上易于理解:使用您的属性定义外部接口需要保留,并将其应用于您的对象。

您可以在“externs 文件”中定义此接口类型,--externs如果您使用命令行,该文件可以包含在带有标志的构建中(请参阅文档中的“声明 Externs”)。

/externs.js
/** @interface */
function ControlsAndConstants() {}
/** @type {number} */
ControlsAndConstants.prototype.lat;
/** @type {number} */
ControlsAndConstants.prototype.lon;
/** @type {number} */
ControlsAndConstants.prototype.rota;
/** @type {number} */
ControlsAndConstants.prototype.zoom;
/** @type {*} */
ControlsAndConstants.prototype.debug;
Run Code Online (Sandbox Code Playgroud) /main.js
// namespace controls and constants
var olc = /** @type {ControlsAndConstants} */ ({
  lon  : 2.0,
  lat  : 25.0,
  rota : 0,
  zoom : 2, // as default
  debug: 'force'
});

window['olc'] = olc;
Run Code Online (Sandbox Code Playgroud)

请注意,不再引用属性名称。我们现在希望 Closure 理解它们,而不是忽略它们。

为什么这样做?externs 文件告诉 Closure “这个ControlsAndConstants接口已经存在并且正在被你没有编译的代码使用。因为你不能优化该代码来重命名属性,你需要自己使用相同的属性名称以实现兼容性。” 够简单!