Source maps is enabled by default when using rails-webpacker. The rask tasks open the manifest file, post the source map to honeybadger and remove the source map file and remove it from the manifest.
yarn add honeybadger-js
in app/javascript/packs/application.js require honeybadger
var Honeybadger = require('honeybadger-js');
Honeybadger.configure({
apiKey: process.env.HONEYBADGER_API_KEY,
environment: process.env.RAILS_ENV,
revision: process.env.SOURCE_VERSION || 'master',
disabled: process.env.NODE_ENV !== 'production'
});
Honeybadger.beforeNotify((err) => {
err.cookies = document.cookie;
return true;
});
It's possible to use process.env thanks to webpacks EnvironmentPlugin
in config/environments/production.rb
config.public_file_server.headers = {
'Access-Control-Allow-Origin' => '*',
'Access-Control-Request-Method' => 'GET,HEAD'
}
Go to aws.amazon.com, Cloudfront, CloudFront Distributions, Your Distribution, Behaviors, Edit, Forward Headers, Whitelist, Add Origin.
In your layout make sure to add crossorigin
javascript_include_tag 'application', 'data-turbolinks-track': 'reload', crossorigin: 'anonymous'
javascript_pack_tag 'application', 'data-turbolinks-track': 'reload', crossorigin: 'anonymous'
The rake tasks runs after webpacker:compile
namespace :honeybadger do
task source_map: :environment do
api_key = ENV['HONEYBADGER_API_KEY']
revision = ENV['SOURCE_VERSION']
manifest_path = Rails.root.join('public', 'packs', 'manifest.json')
manifest = Oj.load(manifest_path.read)
manifest.each do |basename, file_url|
if basename.ends_with?('.map')
puts "[Honeybadger] Sending javascript source map 🐛"
conn = Faraday.new('https://api.honeybadger.io') do |f|
f.request :multipart
f.request :url_encoded
f.adapter Faraday.default_adapter
end
minified_url = "http*:#{file_url.gsub(/\.map$/, '')}"
source_map_file = Faraday::UploadIO.new(Rails.root.join('public', 'packs', File.basename(file_url)).to_s, 'application/octet-stream', File.basename(file_url))
minified_file = Faraday::UploadIO.new(Rails.root.join('public', 'packs', File.basename(file_url.gsub(/\.map$/, ''))).to_s, 'application/javascript', File.basename(file_url.gsub(/\.map$/, '')))
payload = {
api_key: api_key,
minified_url: "http*:#{file_url.gsub(/\.map$/, '')}",
source_map: source_map_file,
minified_file: minified_file,
revision: revision
}
puts "[Honeybadger] Posting #{payload.stringify_keys.inspect}"
response = conn.post('/v1/source_maps', payload)
puts "[Honeybadger] Response #{basename} (#{revision}): #{Rack::Utils::HTTP_STATUS_CODES[response.status]}"
File.delete Rails.root.join('public', 'packs', File.basename(file_url))
end
end
manifest.delete_if { |basename, _| basename.ends_with?('.map') }
File.open(manifest_path, "w") { |f| f.write Oj.dump(manifest, indent: 2) }
end
end
# Compile packs after we've compiled all other assets during precompilation
if Rake::Task.task_defined?("webpacker:compile")
Rake::Task["webpacker:compile"].enhance do
Rake::Task["honeybadger:source_map"].invoke
end
end