diff --git a/Makefile b/Makefile index 669275f34d..934aab75b1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CONTAINER_COMPOSE ?= $(CONTAINER_ENGINE)-compose CONTAINER_ENGINE ?= docker clean: - sudo rm -rfv build/ public/assets/*.js public/assets/*.js.gz public/assets/version.json + sudo rm -rfv build/ public/assets/*.js public/assets/*.js.map public/assets/*.js.gz public/assets/version.json cleandeps: sudo rm -rfv public/assets/deps.js diff --git a/lib/assets.rb b/lib/assets.rb index d00da96158..1750422cf9 100644 --- a/lib/assets.rb +++ b/lib/assets.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'json' require 'opal' require 'snabberb' require 'tempfile' @@ -97,8 +98,8 @@ def builds(titles = []) **game_builds(:all), } else - @_opal ||= compile_lib('opal') - @_deps ||= compile_lib('deps', 'assets') + @_opal ||= compile_lib('opal', 'opal') + @_deps ||= compile_lib('deps_only', 'deps', 'assets') @_engine ||= compile('engine', 'lib', 'engine') @_app ||= compile('app', 'assets/app', '') @@ -164,6 +165,31 @@ def combine(titles = []) @_combined.include?(key) ? next : @_combined.add(key) source = build['files'].map { |file| File.read(file).to_s }.join("\n") + if build['files'].size == 1 + source = File.read(build['files'][0]).to_s + source += "\n//# sourceMappingURL=#{build['path'].delete_prefix('public')}.map\n" + else + source_map = { + 'version' => 3, + 'sections' => [], + } + current_line = 0 + source = build['files'].map do |filepath| + file_source_map = JSON.parse(File.read(filepath + '.map')) + file_source_map['sections'].each do |section| + source_map['sections'].append({ + 'offset' => { 'line' => current_line + section['offset']['line'], 'column' => 0 }, + 'map' => section['map'], + }) + end + + file = File.read(filepath).to_s + current_line += file.lines.count + 1 + file + end.join("\n") + source += "\n//# sourceMappingURL=#{build['path'].delete_prefix('public')}.map\n" + File.write(build['path'] + '.map', source_map.to_json) + end source = compress(key, source) if @compress File.write(build['path'], source) @@ -182,13 +208,14 @@ def combine(titles = []) [@deps_path, @main_path, *game_paths] end - def compile_lib(name, *append_paths) + def compile_lib(output_name, name, *append_paths) builder = Opal::Builder.new append_paths.each { |ap| builder.append_paths(ap) } - path = "#{@out_path}/#{name}.js" - if !@cache || !File.exist?(path) || path == @deps_path + path = "#{@out_path}/#{output_name}.js" + if !@cache || !File.exist?(path) time = Time.now File.write(path, builder.build(name)) + File.write("#{path}.map", builder.source_map.map.to_json) puts "Compiling #{name} - #{Time.now - time}" end path @@ -214,17 +241,30 @@ def compile(name, lib_path, ns = nil, game: nil) time = Time.now File.write(opts[:js_path], compiler.compile) + File.write(opts[:js_path] + '.map', compiler.source_map.map.to_json) puts "Compiling #{file} - #{Time.now - time}" end + source_map = { + 'version' => 3, + 'sections' => [], + } + current_line = 0 source = metadata.map do |_file, opts| - File.read(opts[:js_path]).to_s + file = File.read(opts[:js_path]) + source_map['sections'].append({ + 'offset' => { 'line' => current_line, 'column' => 0 }, + 'map' => JSON.parse(File.read(opts[:js_path] + '.map')), + }) + current_line += file.lines.count + 1 + file end.join("\n") opal_load = game ? "engine/game/#{game}" : name source += "\nOpal.load('#{opal_load}')" File.write(output, source) + File.write(output + '.map', source_map.to_json) output end