ClojureScript优化编译需要在externs文件中使用goog.net.EventType声明

时间:2015-06-01 22:08:46

标签: compilation clojurescript

IFrameIo Clojure Library(https://closure-library.googlecode.com/git-history/docs/class_goog_net_IframeIo.html)可用于促进文件上传。上传过程中最重要的部分之一是事件监听器,一旦文件成功上传,就会调度成功回调:

(goog.events/listen (IframeIo.) (aget goog.net.EventType "SUCCESS") #(success-callback))

这在本地开发环境中工作正常。但是,只要将代码部署到生产环境,即使上载成功,也不再调用success-callback。经过一番调查后,很明显编译过程会破坏goog.net.EventType对象的键:

预期:

Object { SUCCESS: function() ..., ERROR: function() ...}

实际值:

Object { az: function() ..., of: function() ...}

解决此问题的唯一方法是创建一个externs文件依赖项,以防止对象被破坏:

在project.clj中

{:prod
  {:compiler
    {:optimizations :advanced
     :pretty-print false
     :externs ["path/to/googNet-EventType.js"]}}}

googNet-EventType.js:

var goog = {}
goog.net = {}
goog.net.EventType = {}
goog.net.EventType.SUCCESS

编译过程现在保留了goog.net.EventType对象的SUCCESS属性,从而成功调用了回调。

为什么来自goog.net的依赖会破坏它自己的对象?

1 个答案:

答案 0 :(得分:3)

对于这种情况,您不需要外部人员。您与Google Closure Library的交互是导致问题的原因。 Google Closure Library枚举也需要缩小:

(goog.events/listen (IframeIo.) 
  goog.net.EventType.SUCCESS #(success-callback))

是你想要的。我个人会使用ns表单将goog.events别名设为gevents并导入EventType,以便我写一下:

(gevents/listen (IframeIo.) 
  EventType.SUCCESS #(success-callback))

使用属性语法时,你真的不应该使用aget来访问Object属性。如果由于某种原因,您需要使用字符串goog.object.get查找属性。