简体   繁体   English

使用Closure Compiler时,导出库方法的最佳方法是什么?

[英]What is the best way to export library method, when using Closure Compiler?

Closure Compiler documentation clearly states: "Don't use Externs instead of Exports". Closure Compiler文档明确指出:“不要使用Externs而不是Exports”。 Because Externs are very handy to use, I came down with a problem: 因为Externs非常方便使用,所以我遇到了一个问题:

function Lib(){ 
  //some initialization  
}
Lib.prototype = {
  invoke : function(str){
     //this function is called from outside to invoke some of Lib's events
  }  
}

When using Closure Compiler with ADVANCED_OPTIMIZATIONS , function invoke is removed from the source. 使用具有ADVANCED_OPTIMIZATIONS的 Closure Compiler时,将从源中删除函数调用。 This could be prevented in two ways: Adding the line after prototype definition: 这可以通过两种方式来防止:在原型定义后添加行:

Lib.prototype['invoke'] = Lib.prototype.invoke;

But this adds an ugly peace of code at the end of the output code: 但是这会在输出代码的末尾添加一个丑陋的代码:

Lib.prototype.invoke = Lib.prototype.g;

I managed to get rid of this by adding this line to the constructor: 我设法通过将这一行添加到构造函数来摆脱这个:

this.invoke = this.invoke;

And this line to the externs file: 这行到externs文件:

/**
* @param {String} str
*/ 
Lib.prototype.invoke = function(str){};

This way, Closure Compiler can't remove invoke function from the output code, because it is assigned by itself in the constructor, and also, it can't rename it, because it is defined in the externs file. 这样,Closure Compiler不能从输出代码中删除invoke函数,因为它是在构造函数中自己分配的,而且它也不能重命名它,因为它是在externs文件中定义的。 So witch method is better? 那么女巫方法更好?

If you use JSDoc consistently, you could use the @export tag : 如果一致地使用JSDoc,则可以使用@export标记

/**
* @param {String} str
* @export
*/ 
Lib.prototype.invoke = function(str){
     //this function is called from outside to invoke some of Lib's events
};

and call the compiler with the --generate_exports flag. 并使用--generate_exports标志调用编译器。

This requires you to either include base.js from the Google Closure library, or to copy goog.exportSymbol and goog.exportProperty to your codebase. 这要求您包含来自Google Closure库的base.js ,或者将goog.exportSymbolgoog.exportProperty复制到您的代码库。

Personally, I like defining interfaces in externs file and having my internal classes implement them. 就个人而言,我喜欢在externs文件中定义接口并让我的内部类实现它们。

// Externs

/** @interface */
function IInvoke {};
IInvoke.prototype.invoke;

/** 
 *  @constructor
 *  @implements {IInvoke}
 */
function Lib(){ 
  //some initialization  
}
Lib.prototype = {
  invoke : function(str){
     //this function is called from outside to invoke some of Lib's events
  }  
}

You still export the constructor itself, but not the interface methods. 您仍然导出构造函数本身,但不导出接口方法。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM