-
-
Save alexspeller/3730452 to your computer and use it in GitHub Desktop.
# config/initializers/source_maps.rb | |
if Rails.env.development? | |
require 'open3' | |
module CoffeeScript | |
class SourceMapError < StandardError; end; | |
class << self | |
def map_dir | |
return @map_dir if @map_dir | |
# Make the directory the maps are served from | |
@map_dir = Rails.root.join("public/source_maps") | |
@map_dir.mkpath | |
@map_dir | |
end | |
def check_coffeescript_version | |
version = `coffee --version` | |
unless version.match(/(\d+)\.\d+\./)[1].to_i >= 2 | |
raise "You must have coffeescript version 2.0.0-dev or higher to use source maps - see http://ryanflorence.com/2012/coffeescript-source-maps/" | |
end | |
end | |
def compile script, options | |
script = script.read if script.respond_to?(:read) | |
if options.key?(:no_wrap) and !options.key?(:bare) | |
options[:bare] = options[:no_wrap] | |
else | |
options[:bare] = false | |
end | |
check_coffeescript_version | |
compile_with_source_map script, options | |
end | |
def compile_with_source_map script, options | |
flags = %w(--js) | |
flags << "--bare" if options[:bare] | |
javascript, stderr, status = Open3.capture3("coffee #{flags.join(' ')}", stdin_data: script) | |
raise SourceMapError, stderr unless status.success? | |
source_map_comment = generate_source_map options[:pathname], script if options[:pathname] | |
return javascript << source_map_comment | |
rescue SourceMapError => e | |
message = e.message.lines.first.chomp.gsub('"', '\"') | |
relative_path_name = options[:pathname].to_s.gsub(Rails.root.to_s, '') if options[:pathname] | |
relative_path_name ||= '<unknown path>' | |
%Q{throw Error("Coffeescript compile error: #{relative_path_name}: #{message}")} | |
end | |
def generate_source_map pathname, script | |
basename = pathname.basename('.coffee') | |
coffee_file = map_dir.join("#{basename}.coffee") | |
coffee_file.open('w') {|f| f.puts script } | |
# This command actually generates the source map, and saves it to a file | |
source_map, status = nil | |
Dir.chdir Rails.root.join('public/source_maps').to_s do | |
source_map, stderr, status = Open3.capture3("coffee --source-map -i #{pathname.basename}") | |
end | |
raise SourceMapError, "Error while generating source map for file #{pathname}: #{stderr}" unless status.success? | |
# I couldn't figure out how to control the 'file' and 'sources' values in the output, | |
# so parse the map to JSON and rewrite these to ones that will work here | |
data = JSON.parse(source_map) | |
data['file'] = pathname.basename.to_s.gsub(/\.coffee/, '') | |
data['sources'] = [pathname.basename.to_s] | |
map_file = map_dir.join "#{basename}.map" | |
map_file.open('w') { |f| f.puts data.to_json } | |
Rails.logger.info "Compiled source map #{map_file}" | |
return "\n//@ sourceMappingURL=/source_maps/#{map_file.basename}\n" | |
end | |
end | |
end | |
# Monkeypatch this method to include the scripts' pathname | |
require 'tilt/template' | |
module Tilt | |
class CoffeeScriptTemplate < Template | |
def evaluate(scope, locals, &block) | |
@output ||= CoffeeScript.compile(data, options.merge(pathname: scope.pathname)) | |
end | |
end | |
end | |
end |
Could someone please explain how to use this script, or how to get source maps to generate via the pipeline?
I have put source_maps.rb in config/initializers, but not sure what else is required.
I'm new to rails so bear with me ;)
EDIT: Through a bit of searching/looking at the link in the code: I was missing CoffeeScriptRedux - DOH - (a.k.a CoffeeScript 2) - just need to make sure that your dev webserver is using the correct 'coffee' binary (v2.0.0-x). Make sure you restart your server as any files in the /initializers directory won't be 'refreshed'. Also delete your /tmp to make sure your scripts are refreshed and the source map directive is added.
@SimonWade: I ran into the same problem but can't get rid of the semi-colon. Any ideas? I've tried adding newlines
@sdbondi did you menage to solve problem with semi-colon? I`ve got the same.
Hi, not sure exactly what's adding semi-colons in the pipeline this is still working for me as-is on rails version 3.2.12.
Full instructions are available in my blog post about this. @michaltaberski @sdbondi please could you paste an example of actual output with the extra semicolon?
Anyone working on compiling in-process now that the coffee-script-source gem 1.6.1 and later support source maps?
@turadg Here you are!
If this isn't working for you because the generated source maps are missing their filename then try my workaround here: https://gist.github.com/obie/5247309
Issue for underlying problem filed with coffescript project jashkenas/coffeescript#2806
@SimonWade Editing coffee code inside the DevTools debugging isn't possible.
Chrome doesn't know how to run coffeescript, but thanks to CoffeeScriptRedux compiler SMAP feature, it does have a 1 to 1 mapping between the compiled js code to the original coffee code.