【问题标题】:Javascript Module Pattern and Google Closure CompilerJavascript 模块模式和谷歌闭包编译器
【发布时间】:2013-05-15 20:37:46
【问题描述】:

我现在在 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 对象识别为外部对象,但没有运气。不管我怎么尝试,.behaviors.attach 总是被重命名。

有没有办法告诉编译器不要碰整个对象?

【问题讨论】:

  • 我得到 b.behaviors.FOO={attach:function(){}}; ...
  • @dandavis 我通过 SIMPLE_OPTIMIZATIONS 得到了这一点。当我使用 ADVANCED_OPTIMIZATIONS 时,Drupal 对象会被处理,如编辑所示。
  • var o=Drupal['behaviors']['FOO']; o['attach']=init;

标签: javascript drupal google-closure-compiler


【解决方案1】:

没有“不要修改此对象的任何属性”的概念。但是,您可以设置一个外部,例如:

/** @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 命名空间对象作为 范围。闭包编译器不会很好地跟踪此对象中的类型。我列出的注释将用于 jQuery 对象的实例,而不是整个 jQuery 命名空间。这可能不是您想要的。在 Closure-compiler 中处理此问题的唯一类型安全方法是不通过函数闭包传递命名空间。

更新:查看您链接的 JavaScript 模块模式帖子后,他们鼓励将全局命名空间对象传递到函数闭包中。此模式在 Closure-compiler 中存在已知问题。您需要选择遵循这方面的模式或选择与 ADVANCED_OPTIMIZATIONS 完全兼容。

【讨论】:

  • 谢谢,我明天测试一下。当 jQuery 处于 noConflict 模式时,最后一段是否为真?这就是参数的原因。
  • 是的。处理这个问题的方法是使用 Closure-compiler 的 output_wrapper 选项。你会使用类似的东西:--output_wrapper="(function(jQuery){%output%})(jQuery.noConflict())"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多