discourse/lib/ember_cli.rb
David Taylor a0b94dca16
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>
2023-11-07 10:24:49 +00:00

65 lines
1.8 KiB
Ruby

# frozen_string_literal: true
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
def self.assets
@assets ||= Dir.glob("**/*.{js,map,txt}", base: "#{dist_dir}/assets")
end
def self.script_chunks
return @production_chunk_infos if @production_chunk_infos
return self.request_cached_script_chunks if self.request_cached_script_chunks
chunk_infos = JSON.parse(File.read("#{dist_dir}/assets.json"))
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
@production_chunk_infos = chunk_infos if Rails.env.production?
self.request_cached_script_chunks = chunk_infos
rescue Errno::ENOENT
{}
end
def self.is_ember_cli_asset?(name)
assets.include?(name) || script_chunks.values.flatten.include?(name.delete_suffix(".js"))
end
def self.ember_version
@version ||=
begin
ember_source_package_raw =
File.read("#{Rails.root}/app/assets/javascripts/node_modules/ember-source/package.json")
JSON.parse(ember_source_package_raw)["version"]
end
end
def self.workbox_dir_name
return @workbox_base_dir if defined?(@workbox_base_dir)
@workbox_base_dir =
if (full_path = Dir.glob("app/assets/javascripts/discourse/dist/assets/workbox-*")[0])
File.basename(full_path)
end
end
def self.has_tests?
File.exist?("#{dist_dir}/tests/index.html")
end
def self.clear_cache!
@prod_chunk_infos = nil
@assets = nil
self.request_cached_script_chunks = nil
end
end