Javascript 防止闭包编译器在不使用括号表示法的情况下重命名属性

Javascript 防止闭包编译器在不使用括号表示法的情况下重命名属性,javascript,google-closure-compiler,Javascript,Google Closure Compiler,我正在开发一个需要有条件地向最终用户公开API的产品。我们使用闭包编译器进行缩小。我试图公开的API部分是一个函数,该函数使用结果调用回调,其值是具有特定属性的对象 具体来说,我试图公开的函数如下所示(用伪jsdoc表示法): 我想公开的是结果对象API,也就是说,有ok、val和err属性,并公开renderDocument界面,这样提供回调的用户将能够访问状态和图像属性 一种解决方案(可能)是在任何地方使用括号符号,但由于这应该是有条件地公开的(对于某些最终用户),我想从代码中分离出是否缩小

我正在开发一个需要有条件地向最终用户公开API的产品。我们使用闭包编译器进行缩小。我试图公开的API部分是一个函数,该函数使用
结果调用回调,其值是具有特定属性的对象

具体来说,我试图公开的函数如下所示(用伪jsdoc表示法):

我想公开的是
结果
对象API,也就是说,有
ok
val
err
属性,并公开
renderDocument
界面,这样提供回调的用户将能够访问
状态
图像
属性

一种解决方案(可能)是在任何地方使用括号符号,但由于这应该是有条件地公开的(对于某些最终用户),我想从代码中分离出是否缩小的概念

我认为@implements和@export以及一个externs文件的组合可以实现这一点,但我还没有弄明白


我想做的是可能的吗?

处理这种情况有两种主要方法:

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

带有闭包库(或至少是其中的一部分) 如果您愿意在项目中使用闭包库代码的一小部分,可以使用
@export
注释
@export
除非指定了编译标志
--generate\u exports
,否则注释不会执行任何操作

使用
--generate_exports
时,编译器将向闭包库的goog.exportProperty或goog.exportSymbol方法添加适当的调用

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

/** @export */
mynamespace.maybeExposedMethod = function() {};
使用
--generate_exports
标志,编译器将生成以下代码:

var mynamespace = {maybeExposedMethod:function() {}};
goog.exportSymbol("mynamespace.maybeExposedMethod",
    mynamespace.maybeExposedMethod);
而不必依赖于所有的闭包库。您可以将这两个方法的定义复制到源代码中。所需要的只是它们以这些名字的形式存在

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

my_typedefs.js

/** @typedef {{image: string, status: number}} */
var my_record_type;
/** @return {my_record_type} */
function my_method() {
  return {
    image: 'some_image.jpg',
    status: 200
  };
}
my_method_def.js

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

如果
my_typedefs.js
--js
标志一起包含在编译中,则记录属性将被重命名,但如果它与
--externs
标志一起包含,则不会被重命名;对于一个库来说,有时提供函数有时不提供函数是没有意义的。我明白你的意思,但它实际上不是一个库。这是一个专有产品,将提供一个渲染库作为其主要功能的扩展。通常情况下,它都封装在一个IIFE中以防止范围泄漏,但对于某些客户(包括我们的另一个产品),我们会将这些功能公开到全局范围。感谢您的回复。很高兴听到一个非常了解收尾的人的回答。有没有办法调整您上面概述的方法以公开函数返回的对象的属性?例如,我想让属性以类似于
返回{image:someVal,status:someVal}
的方式公开。我可以在某个地方定义一个表示返回值类型的API以使其保持公开吗?@ChrisMiddleton我已经编辑了答案以包含该案例。谢谢!有条件地包含那个extern文件的能力非常适合我正在尝试做的事情。