我现在在Drupal项目上使用Google Closure Compiler。我的Javascript使用Javascript Module Pattern进行结构化。
由于Drupal的工作方式,我正在单独编译每个JS文件。简单编译模式运行良好,但我想在每个文件上使用Advanced Compilation。
我的文件是
的所有变体var FOO = (function(me, $, Drupal, undefined) {
function init (context, settings) {
do_sutff();
};
Drupal.behaviors['FOO'] = {
attach: init
};
return me;
}(FOO || {}, jQuery, Drupal));
我的问题是Drupal.behaviors
是Drupal中的特定对象,attach
属性也是特定属性。当Drupal页面呈现时,Drupal.behaviors
将循环通过,并且所有attach
函数都使用正确的参数进行调用。换句话说,我不希望用Drupal对象重命名任何。
当我使用高级编译模式时,我得到了
var c = function(a, d, b) {
b.b.FOO = {a:function() {
do_stuff()
}};
return a
}(c || {}, jQuery, Drupal);
我试图让编译器将整个Drupal
对象识别为extern而没有运气,尝试了许多变体。无论我尝试什么,.behaviors
和.attach
都会被重命名。
有没有办法告诉编译器保持完整的对象?
答案 0 :(得分:5)
没有概念“不要修改此对象的任何属性”。但是,您可以设置extern,例如:
/** @interface */
function DrupalBehavior() {}
DrupalBehavior.prototype.attach = function(){};
/** @constructor */
function DrupalObject () {}
/** @type {Object.<string, DrupalBehavior>} */
DrupalObject.prototype.behaviors = {};
然后,在您的代码中:
var FOO = (
/**
* @param {Object} me
* @param {jQuery} $
* @param {DrupalObject} Drupal
* @param {*=} undefined
*/
function(me, $, Drupal, undefined) {
function init (context, settings) {
do_sutff();
};
Drupal.behaviors['FOO'] = {
attach: init
};
return me;
}(FOO || {}, jQuery, Drupal));
在这种情况下,Drupal参数将被重命名,但behaviors
属性及其关联的attach
子属性将不会被重命名。
关于jQuery的一个注意事项:您将jQuery命名空间对象作为一个传递给函数 参数。 Closure-compiler不会在此对象中很好地跟踪类型。我列出的注释将用于jQuery对象的实例,而不是整个jQuery命名空间。这可能不是你想要的。在Closure-compiler中处理此问题的唯一类型安全方法是不通过函数闭包传递名称空间。
更新:在查看链接的JavaScript模块模式后,他们鼓励将全局命名空间对象传递到函数闭包中。这种模式已知Closure-compiler的问题。您需要选择遵循这方面的模式,或选择与ADVANCED_OPTIMIZATIONS完全兼容。