rails + sprockets + uglifierでCopyrightを残したままcompressする
環境
デフォルトではcompress時にCopyrightは削除される
このようなenvironments/production.rbがあるとします。
(developmentでもtestでも同じだと思う)
MyApp::Application.configure do config.assets.compress = true config.assets.js_compressor = :uglifier end
その上で rake assets:precompile RAILS_ENV=production
を実行します。
出来上がったjsは結合され、縮小化され、難読化されていてイイコトづくしなのですがCopyrightも消えてしまいます。
MITなどライセンスの表記が必要なjsを使っている場合、これでは困ります。
uglifierはデフォルトではCopyrightを残す
Copyrightを残すかどうかはuglifierのオプションで指定できるのですが、
デフォルトでは残すことになっています。
詳しくは公式に載っています。
sprocketsのデフォルト設定が、Copyrightを無効にしてしまう
デフォルト設定とは、config.assets.js_compressor = :uglifier
のことです。
sprocketsはjs_compressorに指定された値がシンボルだった場合、
そのシンボルをキーにしてデフォルトのCompressorクラスを設定します。
# sprockets-2.10.0/lib/sprockets/compressing.rb def js_compressor=(compressor) unregister_bundle_processor 'application/javascript', js_compressor if js_compressor @js_compressor = nil return unless compressor if compressor.is_a?(Symbol) compressor = compressors['application/javascript'][compressor] || raise(Error, "unknown compressor: #{compressor}") end if compressor.respond_to?(:compress) klass = Class.new(Processor) do @name = "js_compressor" @processor = proc { |context, data| compressor.compress(data) } end @js_compressor = :js_compressor else @js_compressor = klass = compressor end register_bundle_processor 'application/javascript', klass end
ここで設定されるデフォルトのUglifierCompressorというクラスが、実行時にCopyrightオプションを無効にしています。
# sprockets-2.10.0/lib/sprockets/uglifier_compressor.rb def evaluate(context, locals, &block) # Feature detect Uglifier 2.0 option support if Uglifier::DEFAULTS[:copyright] # Uglifier < 2.x Uglifier.new(:copyright => false).compile(data) else # Uglifier >= 2.x Uglifier.new(:comments => :none).compile(data) end end
公式のオプションでは :output => {:comments => :copyright}
ですが
:comments => :copyright
でも動くようにコード内で考慮されています。
シンボルじゃなくてUglifierのインスタンスを設定すればOK
configureの設定方法を次のように変更します。
MyApp::Application.configure do config.assets.compress = true config.assets.js_compressor = Uglifier.new(:comments => :copyright) end
なお、uglifierのバージョンが古い場合はUglifier.new(:copyright => :true)
と指定します。
(ちなみに新しいバージョンでも古い書き方で動くように考慮されているようです)
これで解決です。無事Copyrightが含まれるようになりました。
ただ、sprocketsがデフォルトでCopyrightを消すのが少し不思議です。
消されると困る人の方が多い気がするのですが、何か勘違いしているかな。
おまけ:configureの変更が反映されたりされなかったり?
MyApp::Application.configure
の中身を書き換えて rake assets:precompile RAILS_ENV=production
をしても、
なぜか変更が反映されないことが頻繁にありました。
特定の設定が影響しているわけでもないようで、よく分からず。
以下の手順で必ず反映されるようになりましたが、何が影響しているのだろう。
MyApp::Application.configure
の中身を空にするrake assets:precompile RAILS_ENV=production
(compressされない状態で生成される)- public/assetsを削除
MyApp::Application.configure
の中身を期待するものに更新rake assets:precompile RAILS_ENV=production
追記: コメント欄にて補足頂きましたのでそちらもご覧ください