mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 04:31:10 +08:00
DEV: Use WebPack stats plugin to map entrypoints to chunks (#24239)
Previously, we were parsing webpack JS chunk filenames from the HTML files which ember-cli generates. This worked ok for simple entrypoints, but falls apart once we start using async imports(), which are not included in the HTML. This commit uses the stats plugin to generate an assets.json file, and updates Rails to parse it instead of the HTML. Caching on the Rails side is also improved to avoid reading from the filesystem multiple times per request in develoment. Co-authored-by: Godfrey Chan <godfreykfc@gmail.com>
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module EmberCli
|
||||
class EmberCli < ActiveSupport::CurrentAttributes
|
||||
# Cache which persists for the duration of a request
|
||||
attribute :request_cached_script_chunks
|
||||
|
||||
def self.dist_dir
|
||||
"#{Rails.root}/app/assets/javascripts/discourse/dist"
|
||||
end
|
||||
@ -10,30 +13,23 @@ module EmberCli
|
||||
end
|
||||
|
||||
def self.script_chunks
|
||||
return @chunk_infos if @chunk_infos
|
||||
return @production_chunk_infos if @production_chunk_infos
|
||||
return self.request_cached_script_chunks if self.request_cached_script_chunks
|
||||
|
||||
chunk_infos = {}
|
||||
chunk_infos = JSON.parse(File.read("#{dist_dir}/assets.json"))
|
||||
|
||||
begin
|
||||
test_html = File.read("#{dist_dir}/tests/index.html")
|
||||
chunk_infos.merge! parse_chunks_from_html(test_html)
|
||||
rescue Errno::ENOENT
|
||||
# production build
|
||||
chunk_infos.transform_keys! { |key| key.delete_prefix("assets/").delete_suffix(".js") }
|
||||
|
||||
chunk_infos.transform_values! do |value|
|
||||
value["assets"].map { |chunk| chunk.delete_prefix("assets/").delete_suffix(".js") }
|
||||
end
|
||||
|
||||
index_html = File.read("#{dist_dir}/index.html")
|
||||
chunk_infos.merge! parse_chunks_from_html(index_html)
|
||||
|
||||
@chunk_infos = chunk_infos if Rails.env.production?
|
||||
chunk_infos
|
||||
@production_chunk_infos = chunk_infos if Rails.env.production?
|
||||
self.request_cached_script_chunks = chunk_infos
|
||||
rescue Errno::ENOENT
|
||||
{}
|
||||
end
|
||||
|
||||
def self.parse_source_map_path(file)
|
||||
File.read("#{dist_dir}/assets/#{file}")[%r{//# sourceMappingURL=(.*)$}, 1]
|
||||
end
|
||||
|
||||
def self.is_ember_cli_asset?(name)
|
||||
assets.include?(name) || script_chunks.values.flatten.include?(name.delete_suffix(".js"))
|
||||
end
|
||||
@ -56,31 +52,13 @@ module EmberCli
|
||||
end
|
||||
end
|
||||
|
||||
def self.parse_chunks_from_html(html)
|
||||
doc = Nokogiri::HTML5.parse(html)
|
||||
|
||||
chunk_infos = {}
|
||||
|
||||
doc
|
||||
.css("discourse-chunked-script")
|
||||
.each do |discourse_script|
|
||||
entrypoint = discourse_script.attr("entrypoint")
|
||||
chunk_infos[entrypoint] = discourse_script
|
||||
.css("script[src]")
|
||||
.map do |script|
|
||||
script.attr("src").delete_prefix("#{Discourse.base_path}/assets/").delete_suffix(".js")
|
||||
end
|
||||
end
|
||||
|
||||
chunk_infos
|
||||
end
|
||||
|
||||
def self.has_tests?
|
||||
File.exist?("#{dist_dir}/tests/index.html")
|
||||
end
|
||||
|
||||
def self.clear_cache!
|
||||
@chunk_infos = nil
|
||||
@prod_chunk_infos = nil
|
||||
@assets = nil
|
||||
self.request_cached_script_chunks = nil
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user