阻止Closure Compiler重命名属性而不使用括号表示法

时间:2015-11-19 22:21:19

标签: javascript google-closure-compiler

我正在处理需要有条件地向最终用户公开API的产品。我们正在使用Closure Compiler进行缩小。我尝试公开的API的一部分是一个函数,它调用一个Result的回调,其值是具有某些属性的对象。

具体来说,我尝试公开的函数看起来像这样(用伪jsdoc表示法):

/**
 * @type DocumentRenderResult {status: String, image?: HTMLImageElement|HTMLCanvasElement}
 * @param {function(Result<DocumentRenderResult>)} callback
**/
function renderDocument (url, page, callback) {

}

Result类看起来像这样:

/**
 * @template T
 * @param {Boolean} ok
 * @param {T} val
 * @param {Error} err
**/
function Result (ok, val, err) {
    this.ok = ok;
    this.val = val;
    this.err = err;
}

我想要的是公开Result对象API,即有okvalerr属性的事实,并公开renderDocument界面,以便提供回调的用户能够访问statusimage属性。

一个解决方案(可能)是在任何地方使用括号表示法,但由于这应该只是有条件地暴露(对于某些最终用户),我想分开概念是否从代码中缩小了。

我认为@implements和@export以及externs文件的某些组合可以实现这一点,但我还没有想到它。

我正在尝试做什么?

1 个答案:

答案 0 :(得分:1)

有两种主要方法可以解决这种情况:

没有Closure-Library

将所有导出存储在一个单独的文件中,该文件将成为api公开库的主要入口点。此方法不依赖于外部库。有关此示例,请参阅我的GeolocationMarker library

使用Closure-Library(或至少其中的一部分)

如果您愿意在项目中使用闭包库代码的一小部分,则可以使用@export注释。除非指定了编译标记@export,否则--generate_exports注释不会执行任何操作。

当使用--generate_exports时,编译器会将相应的调用添加到closure-library的goog.exportProperty或goog.exportSymbol方法。

/** @const */
var mynamespace = {};

/** @export */
mynamespace.maybeExposedMethod = function() {};

使用--generate_exports标志,编译器将生成代码:

var mynamespace = {maybeExposedMethod:function() {}};
goog.exportSymbol("mynamespace.maybeExposedMethod",
    mynamespace.maybeExposedMethod);

而不是必须依赖所有的闭包库。您可以将这两种方法的定义复制到源中。所需要的只是它们以那些名字存在。

有条件地重命名记录类型

必须区别对待返回匿名对象的函数以防止重命名。这里最好的选择是在自己的文件中定义记录类型。对于公共api阻止重命名,请将记录定义包含为extern。如果希望重命名记录属性,请将定义包括为源。

<强> my_typedefs.js

/** @typedef {{image: string, status: number}} */
var my_record_type;

<强> my_method_def.js

/** @return {my_record_type} */
function my_method() {
  return {
    image: 'some_image.jpg',
    status: 200
  };
}

如果编译中包含my_typedefs.js --js标志,则会重命名记录属性,但如果它包含在--externs标志中,则不会重命名。