19

在 assets:precompile 期间,javascript 被缩小,但 console.logs 留在里面。

将代码推送到生产环境时,有没有办法在预编译时删除所有 console.logs?

4

4 回答 4

24

从 Uglifier 2.4.0 开始, :compress 选项包括对 :drop_console 的支持,这意味着您可以在 config/environments/production.rb 文件中使用类似的内容轻松删除所有 console.* 函数:

# Compress JavaScripts
config.assets.compress = true
config.assets.js_compressor = Uglifier.new(
  # Remove all console.* functions
  :compress => { :drop_console => true }
) if defined? Uglifier
于 2014-01-23T16:02:28.290 回答
5

您可以将此添加到application.js.erb. 该解决方案将阻止任何日志记录到console.log()生产环境中。但它仍然允许登录到console.error().

<% if Rails.env.production? %>
  window.console = {};
  window.console.log = function(){};
<% else %>
  // the || in the code ensures IE compatability
  window.console = window.console || {};
  window.console.log = window.console.log || function(){};
<% end %>
于 2013-03-16T05:28:39.477 回答
2

要为您指明正确的方向,请查看UglifyJS的用作代码预处理器部分。

我需要研究更多关于如何在 中传递--define DEVMODE=false标志的信息,但是如上面链接中所述,调整代码以使用布尔值rake assets:precompile进行包装应该可以得到您正在寻找的结果。console.logDEVMODE

更新:

在某些将在 期间加载的文件中rake assets:precompile,添加以下猴子补丁。

class Uglifier
  private
    def mangle_options
      {
        "mangle" => @options[:mangle],
        "toplevel" => @options[:toplevel],
        "defines" => { DEVMODE: ["name", "null"] }, # This line sets DEVMODE
        "except" => @options[:except],
        "no_functions" => @options[:mangle] == :vars
      }
    end
end

正如我在下面的评论中提到的,Uglifier不支持传递:definesmangle option。您可以选择将上面标记的行更改为"defines" => @options[:defines]并使用此行更新您的配置

config.assets.js_compressor = Uglifier.new(defines: { DEVMODE: ["name", "null"] })

运行 rake 任务时,DEVMODE现在将null在您的源中转换为。现在,在您的 Javascript 源代码中给出以下代码:

if (typeof DEVMODE === 'undefined') {
  DEVMODE = true;
}

if (DEVMODE) {
  console.log('some log message');
}

默认情况下(在开发模式下)DEVMODE将设置为true,导致console.log()执行。运行时rake assets:precompile,UglifyJS 将设置DEVMODEnull在编译/压缩开始之前。当走过if (null) {它会看到条件永远不会评估true,并将从结果源中删除这个死代码。

只要你console.log()像上面那样写你的电话或速记为

DEVMODE && console.log('some log message');

console.log()调用将从生产代码中删除。除了剥离之外,我还可以看到其他好处console.log(),允许其他特定于开发的代码在开发模式和仅开发模式下与其他 Javascript 共存。

于 2012-08-01T18:24:22.403 回答
2

我想提一下bitcrowd的解决方案。他们的想法基本上是:

  1. 在你的身体标签中定义一个data属性,代表你的应用程序的状态(开发/生产/...) - 例如<body data-env="<%= Rails.env %>">
  2. 根据这一点,让我们console.log()打印出一些东西或什么都不做 - 例如:

    if ($('body').data('env') == 'production' || typeof console == "undefined"){
        var console = { log: function() {}, debug: function() {}, info: function() {} };
    }
    
于 2013-03-05T17:32:17.080 回答