Skip to content

Commit

Permalink
Merge pull request #13 from opal/elia/inline-source-maps
Browse files Browse the repository at this point in the history
Inline sourcemaps and sources content
  • Loading branch information
elia committed Sep 6, 2018
2 parents 6b9536e + cb865c1 commit d8a1d70
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 236 deletions.
12 changes: 12 additions & 0 deletions .travis.yml
Expand Up @@ -17,6 +17,18 @@ matrix:
- rvm: 2.4.4
env: SPROCKETS_VERSION='~> 3.7.1'
- rvm: 2.5.1
env: SPROCKETS_VERSION='~> 3.7.1'

- rvm: 2.1.10
env: OPAL_VERSION='~> 0.11.3' RACK_VERSION='< 2.0.0' SPROCKETS_VERSION='~> 3.4.1'
- rvm: 2.2.10
env: OPAL_VERSION='~> 0.11.3' SPROCKETS_VERSION='~> 3.5.2'
- rvm: 2.3.7
env: OPAL_VERSION='~> 0.11.3' SPROCKETS_VERSION='~> 3.6.3'
- rvm: 2.4.4
env: OPAL_VERSION='~> 0.11.3' SPROCKETS_VERSION='~> 3.7.1'
- rvm: 2.5.1
env: OPAL_VERSION='~> 0.11.3' SPROCKETS_VERSION='~> 3.7.1'

notifications:
irc: "irc.freenode.org#opal"
5 changes: 4 additions & 1 deletion Gemfile
Expand Up @@ -2,7 +2,10 @@ source 'https://rubygems.org'
gemspec

opal_path = File.expand_path('../opal')
if File.exist? opal_path

if ENV['OPAL_VERSION']
gem 'opal', ENV['OPAL_VERSION']
elsif File.exist? opal_path
gem 'opal', path: opal_path
else
gem 'opal', github: 'opal/opal'
Expand Down
20 changes: 15 additions & 5 deletions lib/opal/sprockets/processor.rb
@@ -1,9 +1,9 @@
require 'set'
require 'base64'
require 'tilt/opal'
require 'sprockets'
require 'opal/builder'
require 'opal/sprockets/path_reader'
require 'opal/sprockets/source_map_server'

$OPAL_SOURCE_MAPS = {}

Expand Down Expand Up @@ -49,11 +49,13 @@ def evaluate(context, locals, &block)
process_required_trees(compiler.required_trees, context)

if Opal::Config.source_map_enabled
map_contents = compiler.source_map.as_json.to_json
::Opal::SourceMapServer.set_map_cache(sprockets, logical_path, map_contents)
map_data = compiler.source_map.as_json
# Opal 0.11 doesn't fill sourcesContent
add_sources_content_if_missing(map_data, data)
"#{result}\n#{to_data_uri_comment(map_data.to_json)}"
else
result.to_s
end

result.to_s
end

def self.sprockets_extnames_regexp(sprockets)
Expand Down Expand Up @@ -135,6 +137,14 @@ def self.stub_file(name)

private

def add_sources_content_if_missing(data, content)
data[:sourcesContent] = data.delete(:sourcesContent) || data.delete('sourcesContent') || [content]
end

def to_data_uri_comment(map_to_json)
"//# sourceMappingURL=data:application/json;base64,#{Base64.encode64(map_to_json).delete("\n")}"
end

def stubbed_files
::Opal::Config.stubbed_files
end
Expand Down
20 changes: 1 addition & 19 deletions lib/opal/sprockets/server.rb
@@ -1,15 +1,10 @@
require 'erb'
require 'rack'
require 'opal/source_map'
require 'sprockets'
require 'erb'
require 'opal/sprockets/source_map_server'
require 'opal/sprockets/source_map_header_patch'

module Opal
module Sprockets
class Server
SOURCE_MAPS_PREFIX_PATH = '/__OPAL_SOURCE_MAPS__'

attr_accessor :debug, :use_index, :index_path, :main, :public_root,
:public_urls, :sprockets, :prefix

Expand Down Expand Up @@ -51,25 +46,12 @@ def use_gem gem_name
def create_app
server, sprockets, prefix = self, @sprockets, self.prefix
sprockets.logger.level ||= Logger::DEBUG
source_map_enabled = self.source_map_enabled
if source_map_enabled
maps_prefix = SOURCE_MAPS_PREFIX_PATH
maps_app = SourceMapServer.new(sprockets, maps_prefix)
::Opal::Sprockets::SourceMapHeaderPatch.inject!(maps_prefix)
end

@app = Rack::Builder.app do
not_found = lambda { |env| [404, {}, []] }
use Rack::Deflater
use Rack::ShowExceptions
use Index, server if server.use_index
if source_map_enabled
map(maps_prefix) do
use Rack::ConditionalGet
use Rack::ETag
run maps_app
end
end
map(prefix) { run sprockets }
run Rack::Static.new(not_found, root: server.public_root, urls: server.public_urls)
end
Expand Down
41 changes: 0 additions & 41 deletions lib/opal/sprockets/source_map_header_patch.rb

This file was deleted.

115 changes: 0 additions & 115 deletions lib/opal/sprockets/source_map_server.rb

This file was deleted.

1 change: 0 additions & 1 deletion spec/fixtures/source_map.rb

This file was deleted.

79 changes: 25 additions & 54 deletions spec/sprockets/server_spec.rb
Expand Up @@ -5,8 +5,6 @@
describe Opal::Sprockets::Server do
include Rack::Test::Methods

let(:maps_prefix) { described_class::SOURCE_MAPS_PREFIX_PATH }

def app
described_class.new { |s|
s.main = 'opal'
Expand Down Expand Up @@ -42,67 +40,40 @@ def app
end

describe 'source maps' do
it 'serves map on a top level file' do
get '/assets/source_map.js'
expect(last_response).to be_ok

get maps_prefix+'/source_map.self.map'
expect(last_response).to be_ok
RSpec::Matchers.define :include_inline_source_map do
match do |actual_response|
actual_response.ok? &&
actual_response.body.lines.last.start_with?('//# sourceMappingURL=data:application/json;base64,')
end
end

it 'serves map on a subfolder file' do
js_path = '/assets/source_map/subfolder/other_file.self.js'
map_path = maps_prefix+'/source_map/subfolder/other_file.self.map'

get js_path

expect(last_response).to be_ok
received_map_path = extract_map_path(last_response)
expect(expand_path(received_map_path, js_path+'/..')).to eq(map_path)

get maps_prefix+'/source_map/subfolder/other_file.self.map'
expect(last_response).to be_ok
def extract_inline_map(response)
last_line = response.body.lines.last
b64_encoded = last_line.split('//# sourceMappingURL=data:application/json;base64,', 2)[1]
json_string = Base64.decode64(b64_encoded)
JSON.parse(json_string, symbolize_names: true)
end

it 'serves map on a subfolder file' do
js_path = '/assets/source_map/subfolder/other_file.self.js'
map_path = maps_prefix+'/source_map/subfolder/other_file.self.map'

get js_path
it 'serves map for a top level file' do
get '/assets/opal_file.js'
expect(last_response).to include_inline_source_map

expect(last_response).to be_ok
received_map_path = extract_map_path(last_response)
expect(expand_path(received_map_path, js_path+'/..')).to eq(map_path)
map = extract_inline_map(last_response)

get maps_prefix+'/source_map/subfolder/other_file.self.map'
expect(last_response).to be_ok
map = ::SourceMap::Map.from_json(last_response.body)

if Gem::Version.new(Opal::VERSION) >= Gem::Version.new('0.11.99')
expect(map.sources).to include(maps_prefix+'/source_map/subfolder/other_file.rb')
else
expect(map.sources).to include(maps_prefix+'/source_map/subfolder/other_file')
end
expect(map[:sources]).to eq(['opal_file.rb']).or eq(['opal_file'])
expect(map[:sourcesContent]).to eq(["require 'opal'\nputs 'hi from opal!'\n"])
end
end

def extract_map_path(response)
source_map_comment_regexp = %r{//# sourceMappingURL=(.*)$}
it 'serves map for a subfolder file' do
get '/assets/source_map/subfolder/other_file.self.js'
expect(last_response).to include_inline_source_map

case
when response.body =~ source_map_comment_regexp
body.scan(source_map_comment_regexp).first.first
when response.headers['X-SourceMap']
response.headers['X-SourceMap']
else
raise "cannot find source map in response: #{response.inspect}"
end
end
map = extract_inline_map(last_response)

def expand_path(file_name, dir_string)
path = File.expand_path(file_name, dir_string)
# Remove Windows letter and colon (eg. C:) from path
path = path[2..-1] if !(RUBY_PLATFORM =~ /mswin|mingw/).nil?
path
expect(map[:sources])
.to eq(['source_map/subfolder/other_file.rb'])
.or eq(['source_map/subfolder/other_file'])
expect(map[:sourcesContent]).to eq(["puts 'other!'\n"])
end
end
end

0 comments on commit d8a1d70

Please sign in to comment.