mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 04:31:10 +08:00
DEV: Fix production sourcemaps with Ember CLI (#16707)
22a7905f restructured how we load Ember CLI assets in production. Unfortunately, it also broke sourcemaps for those assets. This commit fixes that regression via a couple of changes: - It adds the necessary `.map` paths to `config.assets.precompile` - It swaps Sprockets' default `SourcemappingUrlProcessor` with an extended version which maintains relative URLs of maps
This commit is contained in:
@ -176,6 +176,7 @@ module Discourse
|
|||||||
Sprockets.register_transformer 'text/x-handlebars', 'application/javascript', Ember::Handlebars::Template
|
Sprockets.register_transformer 'text/x-handlebars', 'application/javascript', Ember::Handlebars::Template
|
||||||
|
|
||||||
require 'discourse_js_processor'
|
require 'discourse_js_processor'
|
||||||
|
require 'discourse_sourcemapping_url_processor'
|
||||||
|
|
||||||
Sprockets.register_mime_type 'application/javascript', extensions: ['.js', '.es6', '.js.es6'], charset: :unicode
|
Sprockets.register_mime_type 'application/javascript', extensions: ['.js', '.es6', '.js.es6'], charset: :unicode
|
||||||
Sprockets.register_postprocessor 'application/javascript', DiscourseJsProcessor
|
Sprockets.register_postprocessor 'application/javascript', DiscourseJsProcessor
|
||||||
@ -184,6 +185,8 @@ module Discourse
|
|||||||
Discourse::Application.initializer :prepend_ember_assets do |app|
|
Discourse::Application.initializer :prepend_ember_assets do |app|
|
||||||
# Needs to be in its own initializer so it runs after the append_assets_path initializer defined by Sprockets
|
# Needs to be in its own initializer so it runs after the append_assets_path initializer defined by Sprockets
|
||||||
app.config.assets.paths.unshift "#{app.config.root}/app/assets/javascripts/discourse/dist/assets"
|
app.config.assets.paths.unshift "#{app.config.root}/app/assets/javascripts/discourse/dist/assets"
|
||||||
|
Sprockets.unregister_postprocessor 'application/javascript', Sprockets::Rails::SourcemappingUrlProcessor
|
||||||
|
Sprockets.register_postprocessor 'application/javascript', DiscourseSourcemappingUrlProcessor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ if EmberCli.enabled?
|
|||||||
scripts/discourse-test-listen-boot
|
scripts/discourse-test-listen-boot
|
||||||
scripts/discourse-boot
|
scripts/discourse-boot
|
||||||
}
|
}
|
||||||
|
Rails.application.config.assets.precompile += EmberCli::ASSETS.map { |name| name.sub('.js', '.map') }
|
||||||
else
|
else
|
||||||
Rails.application.config.assets.precompile += %w{
|
Rails.application.config.assets.precompile += %w{
|
||||||
application.js
|
application.js
|
||||||
|
15
lib/discourse_sourcemapping_url_processor.rb
Normal file
15
lib/discourse_sourcemapping_url_processor.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# This postprocessor rewrites `//sourceMappingURL=` comments to include the hashed filename of the map.
|
||||||
|
# As a side effect, the default implementation also replaces relative sourcemap URLs with absolute URLs, including the CDN domain.
|
||||||
|
# We want to preserve the relative nature of the URLs, so that compiled JS is portable across sites with differing CDN configurations.
|
||||||
|
class DiscourseSourcemappingUrlProcessor < Sprockets::Rails::SourcemappingUrlProcessor
|
||||||
|
def self.sourcemap_asset_path(sourcemap_logical_path, context:)
|
||||||
|
result = super(sourcemap_logical_path, context: context)
|
||||||
|
if File.basename(sourcemap_logical_path) === sourcemap_logical_path
|
||||||
|
# If the original sourcemap reference is relative, keep it relative
|
||||||
|
result = File.basename(result)
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
@ -1,6 +1,15 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module EmberCli
|
module EmberCli
|
||||||
|
ASSETS = %w(
|
||||||
|
discourse.js
|
||||||
|
admin.js
|
||||||
|
ember_jquery.js
|
||||||
|
pretty-text-bundle.js
|
||||||
|
start-discourse.js
|
||||||
|
vendor.js
|
||||||
|
)
|
||||||
|
|
||||||
ALIASES ||= {
|
ALIASES ||= {
|
||||||
"application" => "discourse",
|
"application" => "discourse",
|
||||||
"discourse/tests/test-support-rails" => "test-support",
|
"discourse/tests/test-support-rails" => "test-support",
|
||||||
@ -36,4 +45,9 @@ module EmberCli
|
|||||||
return name if !enabled?
|
return name if !enabled?
|
||||||
ALIASES[name] || name
|
ALIASES[name] || name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.is_ember_cli_asset?(name)
|
||||||
|
return false if !enabled?
|
||||||
|
ASSETS.include?(name) || name.start_with?("chunk.")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,7 +54,7 @@ task 'assets:precompile:before' do
|
|||||||
if EMBER_CLI
|
if EMBER_CLI
|
||||||
# Add ember cli chunks
|
# Add ember cli chunks
|
||||||
Rails.configuration.assets.precompile.push(
|
Rails.configuration.assets.precompile.push(
|
||||||
*EmberCli.script_chunks.values.flatten
|
*EmberCli.script_chunks.values.flatten.flat_map { |name| ["#{name}.js", "#{name}.map"] }
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -189,7 +189,7 @@ end
|
|||||||
|
|
||||||
def max_compress?(path, locales)
|
def max_compress?(path, locales)
|
||||||
return false if Rails.configuration.assets.skip_minification.include? path
|
return false if Rails.configuration.assets.skip_minification.include? path
|
||||||
return false if is_ember_cli_asset?(path)
|
return false if EmberCli.is_ember_cli_asset?(path)
|
||||||
return true unless path.include? "locales/"
|
return true unless path.include? "locales/"
|
||||||
|
|
||||||
path_locale = path.delete_prefix("locales/").delete_suffix(".js")
|
path_locale = path.delete_prefix("locales/").delete_suffix(".js")
|
||||||
|
31
spec/lib/discourse_sourcemapping_url_processor_spec.rb
Normal file
31
spec/lib/discourse_sourcemapping_url_processor_spec.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'discourse_sourcemapping_url_processor'
|
||||||
|
|
||||||
|
describe DiscourseSourcemappingUrlProcessor do
|
||||||
|
def process(input)
|
||||||
|
env = Sprockets::Environment.new
|
||||||
|
env.context_class.class_eval do
|
||||||
|
def resolve(path, **kargs)
|
||||||
|
"/assets/mapped.js.map"
|
||||||
|
end
|
||||||
|
|
||||||
|
def asset_path(path, options = {})
|
||||||
|
"/assets/mapped-HEXGOESHERE.js.map"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
input = { environment: env, data: input, name: 'mapped', filename: 'mapped.js', metadata: {} }
|
||||||
|
DiscourseSourcemappingUrlProcessor.call(input)[:data]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'maintains relative paths' do
|
||||||
|
output = process "var mapped;\n//# sourceMappingURL=mapped.js.map"
|
||||||
|
expect(output).to eq("var mapped;\n//# sourceMappingURL=mapped-HEXGOESHERE.js.map\n//!\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses default behaviour for non-adjacent relative paths' do
|
||||||
|
output = process "var mapped;\n//# sourceMappingURL=/assets/mapped.js.map"
|
||||||
|
expect(output).to eq("var mapped;\n//# sourceMappingURL=/assets/mapped-HEXGOESHERE.js.map\n//!\n")
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue
Block a user