Подтвердить что ты не робот

Удалить console.log по активам прекомпилировать

Во время активов: прекомпиляция javascript будет уменьшена, но console.logs остались.

Есть ли способ удалить все console.logs в precompile, когда код будет перенесен в производство?

4b9b3361

Ответ 1

Как и в Uglifier 2.4.0, опция: compress включает поддержку: drop_console, что означает, что вы можете легко удалить все консольные функции. *, используя что-то подобное в файле config/environment/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

Ответ 2

Вы можете добавить это к 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 %>

Ответ 3

Чтобы указать вам в правильном направлении, ознакомьтесь с Использовать как предварительный процессор кода в разделе UglifyJS.

Мне нужно больше исследовать, как передать флаг --define DEVMODE=false в rake assets:precompile, но при настройке вашего кода на wrap console.log с помощью DEVMODE boolean, как описано в приведенной выше ссылке, вы получите результат вы ищете.

Update:

В каком-то файле, который будет загружаться во время 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 не поддерживает передачу опции :defines mangle. Вы можете по желанию изменить отмеченную строку выше на "defines" => @options[:defines] и обновить конфигурацию с помощью этой строки

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

При запуске задачи рейка 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 в режиме разработки и только.

Ответ 4

Я хотел бы упомянуть решение bitcrowd. Их идея в основном такова:

  • определить атрибут data в теге тела, который представляет состояние вашего приложения (разработка/производство/...) - например. <body data-env="<%= Rails.env %>">
  • в зависимости от этого пусть console.log() распечатать что-нибудь или вообще ничего не делать - например:

    if ($('body').data('env') == 'production' || typeof console == "undefined"){
        var console = { log: function() {}, debug: function() {}, info: function() {} };
    }