From 01107e418e2db2d26364e26822e926759ffd5f55 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 13 Apr 2022 15:03:50 +0100 Subject: [PATCH] DEV: Update to Sprockets 4.0 (#16467) The main difference is that Sprockets 4.0 no longer tries to compile everything by default. This is good for us, because we can remove all our custom 'exclusion' logic which was working around the old sprockets 3.0 behavior. The other big change is that lambdas can no longer be added to the `config.assets.precompile` array. Instead, we can do the necessary globs ourselves, and add the desired files manually. A small patch is required to make ember-rails compatible. Since we plan to remove this dependency in the near future, I do not intend to upstream this change. I have compared the `bin/rake assets:precompile` output before and after this change, and verified that all files are present. --- Gemfile | 4 +-- Gemfile.lock | 4 +-- app/assets/config/manifest.js | 1 + config/application.rb | 31 +++++++----------------- lib/freedom_patches/ember_sprockets_4.rb | 12 +++++++++ 5 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 app/assets/config/manifest.js create mode 100644 lib/freedom_patches/ember_sprockets_4.rb diff --git a/Gemfile b/Gemfile index c66a3f25542..2766c3feadc 100644 --- a/Gemfile +++ b/Gemfile @@ -31,9 +31,7 @@ end gem 'json' -# TODO: At the moment Discourse does not work with Sprockets 4, we would need to correct internals -# This is a desired upgrade we should get to. -gem 'sprockets', '3.7.2' +gem 'sprockets' # this will eventually be added to rails, # allows us to precompile all our templates in the unicorn master diff --git a/Gemfile.lock b/Gemfile.lock index 4b78af90ed5..9de187f37d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -443,7 +443,7 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - sprockets (3.7.2) + sprockets (4.0.3) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.4.2) @@ -602,7 +602,7 @@ DEPENDENCIES shoulda-matchers sidekiq simplecov - sprockets (= 3.7.2) + sprockets sprockets-rails sshkey stackprof diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 00000000000..ac907b36776 --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1 @@ +//= link_tree ../images diff --git a/config/application.rb b/config/application.rb index 1bd7ba921ec..fe08749c862 100644 --- a/config/application.rb +++ b/config/application.rb @@ -142,11 +142,12 @@ module Discourse config.assets.skip_minification = [] # explicitly precompile any images in plugins ( /assets/images ) path - config.assets.precompile += [lambda do |filename, path| - path =~ /assets\/images/ && !%w(.js .css).include?(File.extname(filename)) - end] + Dir.glob("#{config.root}/plugins/*/assets/images/**/*").each do |filename| + config.assets.precompile << filename if !%w(.js .css).include?(File.extname(filename)) + end config.assets.precompile += %w{ + application.js vendor.js admin.js browser-detect.js @@ -193,25 +194,6 @@ module Discourse end end - # out of the box sprockets 3 grabs loose files that are hanging in assets, - # the exclusion list does not include hbs so you double compile all this stuff - initializer :fix_sprockets_loose_file_searcher, after: :set_default_precompile do |app| - app.config.assets.precompile.delete(Sprockets::Railtie::LOOSE_APP_ASSETS) - - # We don't want application from node_modules, only from the root - app.config.assets.precompile.delete(/(?:\/|\\|\A)application\.(css|js)$/) - app.config.assets.precompile += ['application.js'] - - start_path = ::Rails.root.join("app/assets").to_s - exclude = ['.es6', '.hbs', '.hbr', '.js', '.css', '.lock', '.json', '.log', '.html', ''] - app.config.assets.precompile << lambda do |logical_path, filename| - filename.start_with?(start_path) && - !filename.include?("/node_modules/") && - !filename.include?("/dist/") && - !exclude.include?(File.extname(logical_path)) - end - end - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. config.time_zone = 'UTC' @@ -290,6 +272,11 @@ module Discourse Sprockets.register_mime_type 'application/javascript', extensions: ['.js', '.es6', '.js.es6'], charset: :unicode Sprockets.register_postprocessor 'application/javascript', DiscourseJsProcessor + # This class doesn't exist in Sprockets 4, but ember-rails tries to 'autoload' it + # Define an empty class to prevent an error + class Sprockets::Engines + end + require 'discourse_redis' require 'logster/redis_store' # Use redis for our cache diff --git a/lib/freedom_patches/ember_sprockets_4.rb b/lib/freedom_patches/ember_sprockets_4.rb new file mode 100644 index 00000000000..fdfe5c0a748 --- /dev/null +++ b/lib/freedom_patches/ember_sprockets_4.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# One of the initializers in `discourse-ember-rails/lib/ember_rails.rb` tries to set +# the ember template compiler path based on a call to `Sprockets::Environment#resolve` +# which started returning an array in Sprockets 4. +# This doesn't seem to be needed - it was setting to the existing value, so we can just ignore it. +Ember::Handlebars::Template.singleton_class.prepend(Module.new do + def setup_ember_template_compiler(path) + return if path.is_a? Array + super + end +end)