2

高度な最適化モードの Google Closure Compiler は、ファイルを使用して extern を定義します。これにより、外部ライブラリ内のシンボルを参照する変数、プロパティ、および関数名が縮小され、コードが破損するのを防ぐことができます。私の目標は、MooTools フレームワーク (バージョン 1.2 および 1.3) を使用するコードをコンパイルすることですが、コードがクロージャー コンパイラーに供給されるときに MooTools 関数への参照が難読化されるのを防ぐ「公式の」extern ファイルを見つけることができません。私のファイルを正常に処理する次のかなり初歩的なカスタム extern ファイルを思いつきましたが、より良い代替手段 (MooTools ソースから自動生成するなど) はありますか?

//
// Number
//

/**
* @param {number} min
* @param {number} max
* @return {number}
* @nosideeffects
*/
Number.prototype.limit = function (min, max) {}
/**
* @param {number=} precision
* @return {number}
* @nosideeffects
*/
Number.prototype.round = function (precision) {}
Number.prototype.times = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.toFloat = function () {}
/**
* @param {number=} base
* @return {number}
* @nosideeffects
*/
Number.prototype.toInt = function (base) {}

//
// Number.Math
//

/**
* @return {number}
* @nosideeffects
*/
Number.prototype.abs = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.acos = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.asin = function () {}
/**
* @param {number} x
* @return {number}
* @nosideeffects
*/
Number.prototype.atan2 = function (x) {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.ceil = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.cos = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.exp = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.floor = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.log = function () {}
/**
* @param {...number} x
* @return {number}
* @nosideeffects
*/
Number.prototype.max = function (x) {}
/**
* @param {...number} x
* @return {number}
* @nosideeffects
*/
Number.prototype.min = function (x) {}
/**
* @param {number} x
* @return {number}
* @nosideeffects
*/
Number.prototype.pow = function (x) {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.sin = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.sqrt = function () {}
/**
* @return {number}
* @nosideeffects
*/
Number.prototype.tan = function () {}

//
// String
//

/**
* @return {boolean}
* @nosideeffects
*/
String.prototype.test = function () {}
/**
* @return {boolean}
* @nosideeffects
*/
String.prototype.contains = function () {}
/**
* @return {string}
* @nosideeffects
* @suppress {duplicate}
*/
String.prototype.trim = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.clean = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.camelCase = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.hyphenate = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.capitalize = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.escapeRegExp = function () {}
/**
* @return {number}
* @nosideeffects
*/
String.prototype.toInt = function () {}
/**
* @return {number}
* @nosideeffects
*/
String.prototype.toFloat = function () {}
/**
* @return {(string|Array.<number>)}
* @nosideeffects
*/
String.prototype.hexToRgb = function () {}
/**
* @return {(string|Array.<string>)}
* @nosideeffects
*/
String.prototype.rgbToHex = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.substitute = function () {}
/**
* @return {string}
* @nosideeffects
*/
String.prototype.stripScripts = function () {}

//
// Array
//

/**
* @param {function(*, number=, Array=) : undefined} fn
* @param {!Object=} bind
*/
Array.prototype.each = function (fn, bind) {}
Array.prototype.invoke = function () {}
/**
* @param {function(*, number=, Array=) : boolean} fn
* @param {!Object=} bind
* @return {boolean}
* @suppress {duplicate}
*/
Array.prototype.every = function (fn, bind) {}
/**
* @param {function(*, number=, Array=) : boolean} fn
* @param {!Object=} bind
* @return {Array}
* @suppress {duplicate}
*/
Array.prototype.filter = function (fn, bind) {}
/**
* @return Array
*/
Array.prototype.clean = function () {}
/**
* @param {*} item
* @param {number} from
* @return number
* @suppress {duplicate}
*/
Array.prototype.indexOf = function (item, from) {}
/**
* @param {function(*, number=, Array=) : *} fn
* @param {!Object=} bind
* @return {Array}
* @suppress {duplicate}
*/
Array.prototype.map = function (fn, bind) {}
/**
* @param {function(*, number=, Array=) : boolean} fn
* @param {!Object=} bind
* @return {boolean}
* @suppress {duplicate}
*/
Array.prototype.some = function (fn, bind) {}
/**
* @param {Array} obj
* @return {Object}
*/
Array.prototype.associate = function (obj) {}
/**
* @param {Object} obj
* @return {Object}
*/
Array.prototype.link = function (obj) {}
/**
* @param {*} item
* @param {number} from
* @return {boolean}
*/
Array.prototype.contains = function (item, from) {}
/**
* @param {Array} other
* @return {Array}
*/
Array.prototype.append = function (other) {}
/**
* @return {*}
*/
Array.prototype.getLast = function () {}
/**
* @return {*}
*/
Array.prototype.getRandom = function () {}
/**
* @param {*} item
* @return {Array}
*/
Array.prototype.include = function (item) {}
/**
* @param {Array} other
* @return {Array}
*/
Array.prototype.combine = function (other) {}
/**
* @param {*} item
* @return {Array}
*/
Array.prototype.erase = function (item) {}
/**
* @return {Array}
*/
Array.prototype.empty = function () {}
/**
* @return {Array}
*/
Array.prototype.flatten = function () {}
/**
* @return {*}
*/
Array.prototype.pick = function () {}
Array.prototype.hexToRgb = function () {}
Array.prototype.rgbToHex = function () {}

// Class

/**
* @constructor
* @param {(!Object|function())} properties
*/
function Class(properties) { }
/**
* @param {!Object} properties
*/
Class.prototype.implement = function (properties) {}

/**
* @constructor
*/
function Events() { }
/**
* @constructor
*/
function Options() { }

//
// Element
//

/**
* @constructor
* @param {(string|Element)} el
* @param {!Object=} properties
* @suppress {duplicate}
*/
function Element(el, properties) { }
/**
* @param {string} tag
* @return {Element}
*/
Element.prototype.getElement = function (tag) {}
/**
* @param {string} tag
* @return {Elements}
*/
Element.prototype.getElements = function (tag) {}
/**
* @param {string} id
* @return {Element}
*/
Element.prototype.getElementById = function (id) {}
/**
* @param {(string|!Object)} property
* @param {*=} value
* @return {Element}
*/
Element.prototype.set = function (property, value) {}
/**
* @param {string} property
* @return {*}
*/
Element.prototype.get = function (property) {}
/**
* @param {string} property
* @return {*}
*/
Element.prototype.erase = function (property) {}
/**
* @param {(string|Element)} match
* @return {boolean}
*/
Element.prototype.match = function (match) {}
/**
* @param {(string|Element)} el
* @return {boolean}
* @suppress {duplicate}
*/
Element.prototype.contains = function (el) {}
/**
* @param {(string|Element)} el
* @param {string=} where
* @return {Element}
*/
Element.prototype.inject = function (el, where) {}
/**
* @param {(string|Element)} el
* @param {string=} where
* @return {Element}
*/
Element.prototype.grab = function (el, where) {}
/**
* @param {(string|Element|Elements)} el
* @param {...(string|Element|Elements)} var_args
* @return {Element}
*/
Element.prototype.adopt = function (el,var_args) {}
/**
* @param {(string|Element)} el
* @param {string=} where
* @return {Element}
*/
Element.prototype.wraps = function (el, where) {}
/**
* @param {string} text
* @param {string=} where
* @return {Element}
*/
Element.prototype.appendText = function (text, where) {}
/**
* @return {undefined}
*/
Element.prototype.dispose = function () {}
/**
* @param {boolean=} contents
* @param {boolean=} keepid
* @return {Element}
*/
Element.prototype.clone = function (contents, keepid) {}
/**
* @param {(string|Element)} el
* @return {Element}
*/
Element.prototype.replaces = function (el) {}
/**
* @param {string} className
* @return {boolean}
*/
Element.prototype.hasClass = function (className) {}
/**
* @param {string} className
* @return {Element}
*/
Element.prototype.addClass = function (className) {}
/**
* @param {string} className
* @return {Element}
*/
Element.prototype.removeClass = function (className) {}
/**
* @param {string} className
* @param {boolean=} force
* @return {Element}
*/
Element.prototype.toggleClass = function (className, force) {}
/**
* @param {string=} match
* @return {Element}
*/
Element.prototype.getPrevious = function (match) {}
/**
* @param {string=} match
* @return {Elements}
*/
Element.prototype.getAllPrevious = function (match) {}
/**
* @param {string=} match
* @return {Element}
*/
Element.prototype.getNext = function (match) {}
/**
* @param {string=} match
* @return {Elements}
*/
Element.prototype.getAllNext = function (match) {}
/**
* @param {string=} match
* @return {Element}
*/
Element.prototype.getFirst = function (match) {}
/**
* @param {string=} match
* @return {Element}
*/
Element.prototype.getLast = function (match) {}
/**
* @param {string=} match
* @return {Element}
*/
Element.prototype.getParent = function (match) {}
/**
* @param {string=} match
* @return {Elements}
*/
Element.prototype.getParents = function (match) {}
/**
* @param {string=} match
* @return {Elements}
*/
Element.prototype.getSiblings = function (match) {}
/**
* @param {string=} match
* @return {Elements}
*/
Element.prototype.getChildren = function (match) {}
/**
* @return {Element}
*/
Element.prototype.empty = function () {}
Element.prototype.destroy = function () {}
/**
* @return {string}
*/
Element.prototype.toQueryString = function () {}
Element.prototype.getSelected = function () {}
/**
* @param {string} property
* @return {string}
*/
Element.prototype.getProperty = function (property) {}
/**
* @param {Array.<string>} properties
* @return {!Object}
*/
Element.prototype.getProperties = function (properties) {}
/**
* @param {string} property
* @param {*} value
* @return {Element}
*/
Element.prototype.setProperty = function (property, value) {}
/**
* @param {!Object} properties
* @return {Element}
*/
Element.prototype.setProperties = function (properties) {}
/**
* @param {string} property
* @return {Element}
*/
Element.prototype.removeProperty = function (property) {}
/**
* @param {Array.<string>} properties
* @return {Element}
*/
Element.prototype.removeProperties = function (properties) {}
/**
* @param {string} key
* @param {*} value
* @return {Element}
*/
Element.prototype.store = function (key, value) {}
/**
* @param {string} key
* @param {*=} def
* @return {*}
*/
Element.prototype.retrieve = function (key, def) {}
/**
* @param {string} key
* @return {Element}
*/
Element.prototype.eliminate = function (key) {}

/**
* @constructor
* @extends Array
*/
function Elements() { }
/**
* @param {(string|!Object)} property
* @param {*=} value
* @return {Element}
*/
Elements.prototype.set = function (property, value) {}
/**
* @param {string} className
* @return {Element}
*/
Elements.prototype.addClass = function (className) {}
/**
* @param {string} className
* @return {Element}
*/
Elements.prototype.removeClass = function (className) {}
/**
* @param {string} className
* @param {boolean=} force
* @return {Element}
*/
Elements.prototype.toggleClass = function (className, force) {}

/**
* @param {(string|Element)} arg
* @return {Element}
*/
function $(arg) {}
/**
* @param {(string|Array|Element|Elements)} arg
* @param {...Element} var_args
* @return {Elements}
*/
function $$(arg, var_args) {}

//
// Element.Style
//

/**
* @param {string} property
* @return {Element}
*/
Element.prototype.setStyle = function (property, value) {}
/**
* @param {string} property
* @return {string}
*/
Element.prototype.getStyle = function (property) {}
/**
* @param {!Object} styles
* @return {Element}
*/
Element.prototype.setStyles = function (styles) {}
/**
* @param {...string} var_args
*/
Element.prototype.getStyles = function (var_args) {}

//
// Element.Event
//

/**
* @param {string} type
* @param {function()} fn
* @return {Element}
*/
Element.prototype.addEvent = function (type, fn) {}
/**
* @param {string} type
* @param {function()} fn
* @return {Element}
*/
Element.prototype.removeEvent = function (type, fn) {}
/**
* @param {!Object} events
* @return {Element}
*/
Element.prototype.addEvents = function (events) {}
/**
* @param {(string|!Object)=} events
* @return {Element}
*/
Element.prototype.removeEvents = function (events) {}
/**
* @param {string} type
* @param {(Array|Object)=} args
* @param {number=} delay
* @return {Element}
*/
Element.prototype.fireEvent = function (type, args, delay) {}
/**
* @param {Element} from
* @param {string} type
* @return {Element}
*/
Element.prototype.cloneEvents = function (from, type) {}

/**
* @param {string} type
* @param {function()} fn
*/
window.addEvent = function (type, fn) {}
/**
* @param {string} type
* @param {function()} fn
*/
window.removeEvent = function (type, fn) {}
/**
* @param {!Object} events
*/
window.addEvents = function (events) {}
/**
* @param {(string|!Object)=} events
*/
window.removeEvents = function (events) {}
/**
* @param {string} type
* @param {(Array|Object)=} args
* @param {number=} delay
*/
window.fireEvent = function (type, args, delay) {}
/**
* @param {Element} from
* @param {string} type
*/
window.cloneEvents = function (from, type) {}

//
// Element.Dimensions
//

Element.prototype.scrollTo = function () {}
Element.prototype.getSize = function () {}
Element.prototype.getScrollSize = function () {}
Element.prototype.getScroll = function () {}
Element.prototype.getPosition = function () {}
Element.prototype.setPosition = function () {}
Element.prototype.getCoordinates = function () {}
Element.prototype.getOffsetParent = function () {}

window.scrollTo = function () {}
window.getSize = function () {}
window.getScrollSize = function () {}
window.getScroll = function () {}

//
// Fx
//

/**
* @constructor
*/
function Fx() {}
/**
* @constructor
* @param {(string|Element)} el
* @param {!Object=} options
*/
Fx.Tween = function (el, options) { }
Fx.Tween.prototype.set = function () { }
Fx.Tween.prototype.start = function () { }
/**
* @constructor
* @param {(string|Element)} el
* @param {!Object=} options
*/
Fx.Morph = function (el, options) { }
/**
* @param {(string|!Object)} properties
* @return {Fx.Morph}
*/
Fx.Morph.prototype.set = function (properties) { }
/**
* @param {(string|!Object)} properties
* @return {Fx.Morph}
*/
Fx.Morph.prototype.start = function (properties) { }

/**
* @return {Element}
*/
Element.prototype.tween = function () {}
/**
* @return {Element}
*/
Element.prototype.morph = function () {}
/**
* @return {Element}
*/
Element.prototype.fade = function () {}
/**
* @return {Element}
*/
Element.prototype.highlight = function () {}

//
// Fx.Transitions
//

/**
* @constructor
*/
Fx.Transitions = function () {}
Fx.Transitions.linear = function () {}
Fx.Transitions.quad = function () {}
Fx.Transitions.cubic = function () {}
Fx.Transitions.quart = function () {}
Fx.Transitions.quint = function () {}
Fx.Transitions.pow = function () {}
Fx.Transitions.expo = function () {}
Fx.Transitions.circ = function () {}
Fx.Transitions.sine = function () {}
Fx.Transitions.back = function () {}
Fx.Transitions.bounce = function () {}
Fx.Transitions.elastic = function () {}

//
// Request
//

/**
* @constructor
* @param {!Object=} options
*/
function Request(options) { }
Request.prototype.setHeader = function () {}
Request.prototype.getHeader = function () {}
Request.prototype.send = function () {}
Request.prototype.post = function () {}
Request.prototype.get = function () {}
Request.prototype.put = function () {}
Request.prototype.cancel = function () {}
Request.prototype.isRunning = function () {}

Element.prototype.send = function () {}

/**
* @constructor
* @extends Request
* @param {!Object=} options
*/
Request.HTML = function (options) { }
/**
* @constructor
* @extends Request
* @param {!Object=} options
*/
Request.JSON = function (options) { }

//
// JSON
//

/**
* @constructor
*/
function JSON() { }
/**
* @param {Object} obj
* @return {string}
*/
JSON.encode = function (obj) {}
/**
* @param {string} string
* @param {boolean=} secure
*/
JSON.decode = function (string, secure) {}

//
// Swiff
//

/**
* @constructor
* @param {string} path
* @param {!Object} options
*/
function Swiff(path, options) { }

//
// Compat
//

/**
* @param {...*} var_args
* @nosideeffects
*/
function $pick(var_args) { }
/**
* @param {...Object} var_args
* @nosideeffects
*/
function $merge(var_args) { }
4

2 に答える 2

2

包括的な拡張ファイルは、Closure Compiler を Advanced モードで使用する最初のステップにすぎません。ライブラリ自体を使用可能にするには、作成 (または変更) する必要があります。

externs ファイルは、プロパティと関数の名前変更という 1 つの種類の問題のみを防止するだけです。ただし、ライブラリ コード ベースが慎重にスクラブされていないと、一部のコード構造がコンパイル後に壊れる可能性があります。

たとえば、デッドコードの削除では、間違ったコードを簡単に削除できます (または、削除する必要があるコードを残します)。意図しないエイリアスは、ほとんどの最適化の実行を妨げる可能性があります。「これの危険な使用」は、最も疑いのない場所でコードを壊す可能性があります。

したがって、externs ファイルでコードがコンパイルされて正常に動作したとしても、他の MooTools プログラムが正常に動作するとは限りません。さらに、コンパイル中に壊れる機能を知らずに使用しても、プログラムの次のリビジョンが壊れないという意味ではありません。

于 2011-04-03T06:28:07.643 に答える
0

クロージャー コンパイラによって提供された externs ファイルはhttp://code.google.com/p/closure-compiler/source/browse/#svn%2Ftrunk%2Fcontrib%2Fexternsにあります。ご覧のとおり、一般的なライブラリの externs ファイルが多数あります。

動作するものがある場合は、それを使用して、mootools extern を使用してクロージャ コンパイラの担当者にパッチを送信してください。そうすれば、たくさんの人がそれを維持するのを手伝うことができます。問題へのアップロードとしてパッチを喜んで受け取ります: http://code.google.com/p/closure-compiler/issues/list

于 2011-04-02T17:49:27.320 に答える