删除资产预编译上的console.log

时间:2012-08-01 17:56:27

标签: ruby-on-rails ruby-on-rails-3 asset-pipeline

在资产期间:预编译javascript被缩小,但是console.logs保留在。

有什么方法可以在代码推送到生产时删除预编译中的所有console.log?

4 个答案:

答案 0 :(得分:23)

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

# Compress JavaScripts
config.assets.compress = true
config.assets.js_compressor = Uglifier.new(
  # Remove all console.* functions
  :compress => { :drop_console => true }
) if defined? Uglifier

答案 1 :(得分: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 %>

答案 2 :(得分:2)

要指出正确的方向,请查看 Use as a code pre-processor UglifyJS 部分。

我需要研究更多关于如何在--define DEVMODE=false内传递rake assets:precompile标志,但调整代码以使用console.log布尔包裹DEVMODE,如上所述上面的链接可以为您提供您正在寻找的结果。

<强>更新

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 does not support passing a :defines mangle 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将在编译/压缩开始之前将DEVMODE设置为null。走过if (null) {时,它会看到条件永远不会评估true,并会从结果源中删除此死代码。

只要您将上述console.log()来电或简写为

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

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

答案 3 :(得分: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() {} };
    }