mirror of
https://github.com/discourse/discourse.git
synced 2025-05-10 06:43:07 +08:00
PERF: Compile main locale bundles just-in-time (#32335)
Previously all locale bundles would be built & compressed during assets:precompile. For most sites, only one of these languages was actually used, so this is fairly wasteful. This commit moves the main locale bundle into the ExtraLocalesController, which has recently undergone many improvements to make it more efficient. This allows locale files to be bundled "just in time" when they're first accessed. Now that brotli level=6 is enabled for these assets in our nginx config, this change should have no impact on the locale bundle size.
This commit is contained in:
parent
3b9d9f5893
commit
c62a4a4759
6
Gemfile
6
Gemfile
@ -117,12 +117,6 @@ gem "net-imap", require: false
|
||||
gem "net-pop", require: false
|
||||
gem "digest", require: false
|
||||
|
||||
# Gems used only for assets and not required in production environments by default.
|
||||
# Allow everywhere for now cause we are allowing asset debugging in production
|
||||
group :assets do
|
||||
gem "uglifier"
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "capybara", require: false
|
||||
gem "webmock", require: false
|
||||
|
@ -610,8 +610,6 @@ GEM
|
||||
concurrent-ruby (~> 1.0)
|
||||
tzinfo-data (1.2025.2)
|
||||
tzinfo (>= 1.0.0)
|
||||
uglifier (4.2.1)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.2.0)
|
||||
unicode-display_width (3.1.4)
|
||||
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||
@ -791,7 +789,6 @@ DEPENDENCIES
|
||||
thor
|
||||
trilogy
|
||||
tzinfo-data
|
||||
uglifier
|
||||
unf
|
||||
unicorn
|
||||
web-push
|
||||
@ -1085,7 +1082,6 @@ CHECKSUMS
|
||||
trilogy (2.9.0) sha256=a2d63b663ba68a4758e15d1f9afb228f5d16efc7fe7cea68699e1c106ef6067f
|
||||
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
||||
tzinfo-data (1.2025.2) sha256=a92375a1fbb47d38fe88fd514c40a38cc8f97d168da2a6479f15185e86470939
|
||||
uglifier (4.2.1) sha256=75d42b81b10bfd21e7a427fabb1d49ff5ea7bda3c4a5039ddb2a78d194c6f5aa
|
||||
unf (0.2.0) sha256=e6bcc2e101d80e3f9459753db747d5926aada1aaaf61e629e93359da9a5b04ab
|
||||
unicode-display_width (3.1.4) sha256=8caf2af1c0f2f07ec89ef9e18c7d88c2790e217c482bfc78aaa65eadd5415ac1
|
||||
unicode-emoji (4.0.4) sha256=2c2c4ef7f353e5809497126285a50b23056cc6e61b64433764a35eff6c36532a
|
||||
|
@ -216,9 +216,6 @@ if (themeTestPages) {
|
||||
} else {
|
||||
// Running with ember cli, but we want to pass through plugin request to Rails
|
||||
module.exports.proxies = {
|
||||
"/assets/locales/*.js": {
|
||||
target,
|
||||
},
|
||||
"/assets/plugins/*_extra.js": {
|
||||
target,
|
||||
},
|
||||
|
@ -53,7 +53,7 @@
|
||||
|
||||
<script src="{{rootURL}}assets/discourse.js"></script>
|
||||
|
||||
<script src="{{rootURL}}assets/locales/en.js" data-embroider-ignore></script>
|
||||
<script src="{{rootURL}}extra-locales/0000000000000000000000000000000000000000/en/main.js" data-embroider-ignore></script>
|
||||
<script src="{{rootURL}}extra-locales/0000000000000000000000000000000000000000/en/mf.js" data-embroider-ignore></script>
|
||||
<script src="{{rootURL}}extra-locales/0000000000000000000000000000000000000000/en/admin.js" data-embroider-ignore></script>
|
||||
<script src="{{rootURL}}extra-locales/0000000000000000000000000000000000000000/en/wizard.js" data-embroider-ignore></script>
|
||||
|
@ -1,11 +0,0 @@
|
||||
//= depend_on 'client.ar.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ar) %>
|
||||
|
||||
// original moment.js implementation can be found here:
|
||||
// https://github.com/moment/moment/blob/b7ec8e2ec068e03de4f832f28362675bb9e02261/locale/ar.js#L185-L191
|
||||
moment.updateLocale("ar", {
|
||||
postformat(string) {
|
||||
return string;
|
||||
}
|
||||
});
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.be.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:be) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.bg.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:bg) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.bs_BA.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:bs_BA) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ca.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ca) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.cs.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:cs) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.da.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:da) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.de.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:de) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.el.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:el) %>
|
@ -1,5 +0,0 @@
|
||||
//= depend_on 'client.en.yml'
|
||||
//= require locales/i18n
|
||||
|
||||
<% JsLocaleHelper.reloadable_plugins(:en, self) %>
|
||||
<%= JsLocaleHelper.output_locale(:en) %>
|
@ -1,6 +0,0 @@
|
||||
//= depend_on 'client.en_GB.yml'
|
||||
//= depend_on 'client.en.yml'
|
||||
//= require locales/i18n
|
||||
|
||||
<% JsLocaleHelper.reloadable_plugins(:en_GB, self) %>
|
||||
<%= JsLocaleHelper.output_locale(:en_GB) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.es.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:es) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.et.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:et) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.fa_IR.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:fa_IR) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.fi.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:fi) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.fr.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:fr) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.gl.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:gl) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.he.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:he) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.hr.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:hr) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.hu.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:hu) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.hy.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:hy) %>
|
@ -1,2 +0,0 @@
|
||||
require("discourse/loader-shims");
|
||||
require("discourse-i18n");
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.id.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:id) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.it.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:it) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ja.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ja) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ko.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ko) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.lt.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:lt) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.lv.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:lv) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.nb_NO.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:nb_NO) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.nl.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:nl) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.pl_PL.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:pl_PL) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.pt.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:pt) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.pt_BR.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:pt_BR) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ro.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ro) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ru.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ru) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.sk.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sk) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.sl.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sl) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.sq.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sq) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.sr.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sr) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.sv.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sv) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.sw.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sw) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.te.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:te) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.th.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:th) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.tr_TR.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:tr_TR) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ug.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ug) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.uk.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:uk) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.ur.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:ur) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.vi.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:vi) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.zh_CN.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:zh_CN) %>
|
@ -1,3 +0,0 @@
|
||||
//= depend_on 'client.zh_TW.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:zh_TW) %>
|
@ -11,12 +11,13 @@ class ExtraLocalesController < ApplicationController
|
||||
|
||||
OVERRIDES_BUNDLE = "overrides"
|
||||
SHA1_HASH_LENGTH = 40
|
||||
MAIN_BUNDLE = "main"
|
||||
MF_BUNDLE = "mf"
|
||||
ADMIN_BUNDLE = "admin"
|
||||
WIZARD_BUNDLE = "wizard"
|
||||
|
||||
SITE_SPECIFIC_BUNDLES = [OVERRIDES_BUNDLE, MF_BUNDLE]
|
||||
SHARED_BUNDLES = [ADMIN_BUNDLE, WIZARD_BUNDLE]
|
||||
SHARED_BUNDLES = [MAIN_BUNDLE, ADMIN_BUNDLE, WIZARD_BUNDLE]
|
||||
|
||||
class << self
|
||||
def js_digests
|
||||
@ -63,6 +64,8 @@ class ExtraLocalesController < ApplicationController
|
||||
JsLocaleHelper.output_client_overrides(locale_str)
|
||||
when MF_BUNDLE
|
||||
JsLocaleHelper.output_MF(locale_str)
|
||||
when MAIN_BUNDLE
|
||||
JsLocaleHelper.output_locale(locale_str)
|
||||
else
|
||||
JsLocaleHelper.output_extra_locales(bundle_str, locale_str)
|
||||
end
|
||||
|
@ -36,7 +36,7 @@
|
||||
<%= preload_script file %>
|
||||
<%- end %>
|
||||
|
||||
<%= preload_script "locales/#{I18n.locale}" %>
|
||||
<%= preload_script_url ExtraLocalesController.url("main") %>
|
||||
<%= preload_script_url ExtraLocalesController.url("mf") %>
|
||||
<%- if ExtraLocalesController.client_overrides_exist? %>
|
||||
<%= preload_script_url ExtraLocalesController.url("overrides") %>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<%= preload_script "test-support" %>
|
||||
<%= preload_script "discourse" %>
|
||||
<%= preload_script "test" %>
|
||||
<%= preload_script "locales/#{I18n.locale}" %>
|
||||
<%= preload_script_url ExtraLocalesController.url("main") %>
|
||||
<%= preload_script_url ExtraLocalesController.url("mf") %>
|
||||
<%= preload_script "admin" %>
|
||||
<%- Discourse.find_plugin_js_assets(include_disabled: true).each do |file| %>
|
||||
|
@ -117,9 +117,6 @@ module Discourse
|
||||
# :all can be used as a placeholder for all plugins not explicitly named.
|
||||
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
||||
|
||||
# Allows us to skip minification on some files
|
||||
config.assets.skip_minification = []
|
||||
|
||||
# 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"
|
||||
|
@ -9,7 +9,6 @@ Rails.application.config.assets.enabled = true
|
||||
Rails.application.config.assets.version = "2-#{GlobalSetting.asset_url_salt}"
|
||||
|
||||
# Add additional assets to the asset load path.
|
||||
Rails.application.config.assets.paths << "#{Rails.root}/config/locales"
|
||||
Rails.application.config.assets.paths << "#{Rails.root}/public/javascripts"
|
||||
|
||||
# Precompile additional assets.
|
||||
@ -23,29 +22,12 @@ Rails.application.config.assets.precompile += [
|
||||
end,
|
||||
]
|
||||
|
||||
Rails.application.config.assets.precompile += %w[
|
||||
break_string.js
|
||||
locales/i18n.js
|
||||
scripts/discourse-test-listen-boot
|
||||
]
|
||||
Rails.application.config.assets.precompile += %w[break_string.js scripts/discourse-test-listen-boot]
|
||||
|
||||
Rails.application.config.assets.precompile << lambda do |logical_path, filename|
|
||||
filename.start_with?(EmberCli.dist_dir) && EmberCli.assets.include?(logical_path)
|
||||
end
|
||||
|
||||
# Precompile all available locales
|
||||
unless GlobalSetting.try(:omit_base_locales)
|
||||
Dir
|
||||
.glob("#{Rails.root}/app/assets/javascripts/locales/*.js.erb")
|
||||
.each do |file|
|
||||
Rails
|
||||
.application
|
||||
.config
|
||||
.assets
|
||||
.precompile << "locales/#{file.match(/([a-z_A-Z]+\.js)\.erb$/)[1]}"
|
||||
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
|
||||
Rails.application.config.assets.precompile.delete(Sprockets::Railtie::LOOSE_APP_ASSETS)
|
||||
|
@ -187,7 +187,10 @@ module JsLocaleHelper
|
||||
translations = translations_for(locale_str)
|
||||
|
||||
remove_message_formats!(translations, locale)
|
||||
result = +""
|
||||
result = +<<~JS
|
||||
require("discourse/loader-shims");
|
||||
require("discourse-i18n");
|
||||
JS
|
||||
|
||||
translations.keys.each do |l|
|
||||
translations[l].keys.each { |k| translations[l].delete(k) unless k == "js" }
|
||||
|
@ -1429,7 +1429,6 @@ class Plugin::Instance
|
||||
""
|
||||
opts[:server_locale_file] = Dir["#{root_path}/config/locales/server*.#{locale}.yml"].first ||
|
||||
""
|
||||
opts[:js_locale_file] = File.join(root_path, "assets/locales/#{locale}.js.erb")
|
||||
|
||||
locale_chain = opts[:fallbackLocale] ? [locale, opts[:fallbackLocale]] : [locale]
|
||||
lib_locale_path = File.join(root_path, "lib/javascripts/locale")
|
||||
@ -1522,8 +1521,7 @@ class Plugin::Instance
|
||||
|
||||
def valid_locale?(custom_locale)
|
||||
File.exist?(custom_locale[:client_locale_file]) &&
|
||||
File.exist?(custom_locale[:server_locale_file]) &&
|
||||
File.exist?(custom_locale[:js_locale_file]) && custom_locale[:moment_js]
|
||||
File.exist?(custom_locale[:server_locale_file]) && custom_locale[:moment_js]
|
||||
end
|
||||
|
||||
def find_locale_file(locale_chain, path)
|
||||
|
@ -34,7 +34,6 @@ task "assets:precompile:before": %w[
|
||||
assets:precompile:prereqs
|
||||
assets:precompile:build
|
||||
] do
|
||||
require "uglifier"
|
||||
require "open3"
|
||||
|
||||
# Ensure we ALWAYS do a clean build
|
||||
@ -42,13 +41,8 @@ task "assets:precompile:before": %w[
|
||||
STDERR.puts "Purging temp files"
|
||||
`rm -fr #{Rails.root}/tmp/cache`
|
||||
|
||||
$node_compress = !ENV["SKIP_NODE_UGLIFY"]
|
||||
|
||||
unless ENV["USE_SPROCKETS_UGLIFY"]
|
||||
$bypass_sprockets_uglify = true
|
||||
Rails.configuration.assets.js_compressor = nil
|
||||
Rails.configuration.assets.gzip = false
|
||||
end
|
||||
Rails.configuration.assets.js_compressor = nil
|
||||
Rails.configuration.assets.gzip = false
|
||||
|
||||
STDERR.puts "Bundling assets"
|
||||
|
||||
@ -127,54 +121,12 @@ def cdn_relative_path(p)
|
||||
global_path_klass.cdn_relative_path(p)
|
||||
end
|
||||
|
||||
def compress_node(from, to)
|
||||
to_path = "#{assets_path}/#{to}"
|
||||
assets = cdn_relative_path("/assets")
|
||||
assets_additional_path = (d = File.dirname(from)) == "." ? "" : "/#{d}"
|
||||
source_map_root = assets + assets_additional_path
|
||||
source_map_url = "#{File.basename(to)}.map"
|
||||
base_source_map = assets_path + assets_additional_path
|
||||
|
||||
cmd = <<~SH
|
||||
pnpm terser '#{assets_path}/#{from}' -m -c -o '#{to_path}' --source-map "base='#{base_source_map}',root='#{source_map_root}',url='#{source_map_url}',includeSources=true"
|
||||
SH
|
||||
|
||||
STDERR.puts cmd
|
||||
result = `#{cmd} 2>&1`
|
||||
unless $?.success?
|
||||
STDERR.puts result
|
||||
exit 1
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def compress_ruby(from, to)
|
||||
data = File.read("#{assets_path}/#{from}")
|
||||
|
||||
uglified, map =
|
||||
Uglifier.new(
|
||||
comments: :none,
|
||||
source_map: {
|
||||
filename: File.basename(from),
|
||||
output_filename: File.basename(to),
|
||||
},
|
||||
).compile_with_map(data)
|
||||
dest = "#{assets_path}/#{to}"
|
||||
|
||||
File.write(dest, uglified << "\n//# sourceMappingURL=#{cdn_path "/assets/#{to}.map"}")
|
||||
File.write(dest + ".map", map)
|
||||
|
||||
GC.start
|
||||
end
|
||||
|
||||
def gzip(path)
|
||||
STDERR.puts "gzip -f -c -9 #{path} > #{path}.gz"
|
||||
STDERR.puts `gzip -f -c -9 #{path} > #{path}.gz`.strip
|
||||
raise "gzip compression failed: exit code #{$?.exitstatus}" if $?.exitstatus != 0
|
||||
end
|
||||
|
||||
# different brotli versions use different parameters
|
||||
def brotli_command(path)
|
||||
compression_quality = ENV["DISCOURSE_ASSETS_PRECOMPILE_DEFAULT_BROTLI_QUALITY"] || "6"
|
||||
"brotli -f --quality=#{compression_quality} #{path} --output=#{path}.br"
|
||||
@ -188,21 +140,6 @@ def brotli(path)
|
||||
raise "chmod failed: exit code #{$?.exitstatus}" if $?.exitstatus != 0
|
||||
end
|
||||
|
||||
def max_compress?(path, locales)
|
||||
return false if Rails.configuration.assets.skip_minification.include? path
|
||||
return false if EmberCli.is_ember_cli_asset?(path)
|
||||
return true if path.exclude? "locales/"
|
||||
|
||||
path_locale = path.delete_prefix("locales/").delete_suffix(".js")
|
||||
return true if locales.include? path_locale
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def compress(from, to)
|
||||
$node_compress ? compress_node(from, to) : compress_ruby(from, to)
|
||||
end
|
||||
|
||||
def concurrent?
|
||||
if ENV["SPROCKETS_CONCURRENT"] == "1"
|
||||
concurrent_compressors = []
|
||||
@ -249,30 +186,13 @@ task "assets:precompile:compress_js": "environment" do
|
||||
.select { |k, v| k =~ /\.js\z/ }
|
||||
.each do |file, info|
|
||||
path = "#{assets_path}/#{file}"
|
||||
_file =
|
||||
(
|
||||
if (d = File.dirname(file)) == "."
|
||||
"_#{file}"
|
||||
else
|
||||
"#{d}/_#{File.basename(file)}"
|
||||
end
|
||||
)
|
||||
_path = "#{assets_path}/#{_file}"
|
||||
max_compress = max_compress?(info["logical_path"], locales)
|
||||
if File.exist?(_path)
|
||||
STDERR.puts "Skipping: #{file} already compressed"
|
||||
elsif file.include? "discourse/tests"
|
||||
if file.include? "discourse/tests"
|
||||
STDERR.puts "Skipping: #{file}"
|
||||
else
|
||||
proc.call do
|
||||
log_task_duration(file) do
|
||||
STDERR.puts "Compressing: #{file}"
|
||||
|
||||
if max_compress
|
||||
FileUtils.mv(path, _path)
|
||||
compress(_file, file)
|
||||
end
|
||||
|
||||
info["size"] = File.size(path)
|
||||
info["mtime"] = File.mtime(path).iso8601
|
||||
gzip(path)
|
||||
|
@ -1,2 +0,0 @@
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:foo_BAR) %>
|
@ -1,2 +0,0 @@
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:tlh) %>
|
@ -1,2 +0,0 @@
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:tup) %>
|
@ -22,12 +22,9 @@ RSpec.describe JsLocaleHelper do
|
||||
ctx.eval <<~JS
|
||||
define("discourse/loader-shims", () => {})
|
||||
define("discourse/lib/load-moment", () => {})
|
||||
moment = { defineLocale: () => {}, fn: {}, tz: {} }
|
||||
require("discourse-i18n");
|
||||
globalThis.moment = { defineLocale: () => {}, fn: {}, tz: {} }
|
||||
JS
|
||||
# As there are circular references in the return value, this raises an
|
||||
# error if we let MiniRacer try to convert the value to JSON. Forcing
|
||||
# returning `null` from `#eval` will prevent that.
|
||||
ctx.eval("#{File.read("#{Rails.root}/app/assets/javascripts/locales/i18n.js")};null")
|
||||
ctx
|
||||
end
|
||||
|
||||
|
@ -607,7 +607,6 @@ TEXT
|
||||
config/locales/client.foo_BAR.yml
|
||||
config/locales/server.foo_BAR.yml
|
||||
lib/javascripts/locale/moment_js/foo_BAR.js
|
||||
assets/locales/foo_BAR.js.erb
|
||||
].each do |path|
|
||||
it "does not register a new locale when #{path} is missing" do
|
||||
path = "#{plugin_path}/#{path}"
|
||||
|
@ -1074,11 +1074,13 @@ RSpec.describe ApplicationController do
|
||||
{ HTTP_ACCEPT_LANGUAGE: locale }
|
||||
end
|
||||
|
||||
def locale_scripts(body)
|
||||
def main_locale_scripts(body)
|
||||
Nokogiri::HTML5
|
||||
.parse(body)
|
||||
.css('script[src*="assets/locales/"]')
|
||||
.map { |script| script.attributes["src"].value }
|
||||
.css('script[src*="extra-locales/"]')
|
||||
.filter_map do |script|
|
||||
script.attributes["src"].to_s[%r{extra-locales/[^/]+/([^/]+)/main.js}, 1]
|
||||
end
|
||||
end
|
||||
|
||||
context "with allow_user_locale disabled" do
|
||||
@ -1092,7 +1094,7 @@ RSpec.describe ApplicationController do
|
||||
it "uses the default locale" do
|
||||
get "/latest", headers: headers("fr")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("en")
|
||||
end
|
||||
end
|
||||
|
||||
@ -1103,7 +1105,7 @@ RSpec.describe ApplicationController do
|
||||
|
||||
get "/latest", headers: headers("fr")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("en")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1121,13 +1123,13 @@ RSpec.describe ApplicationController do
|
||||
it "uses the locale from the headers" do
|
||||
get "/latest", headers: headers("fr")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/fr.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("fr")
|
||||
end
|
||||
|
||||
it "doesn't leak after requests" do
|
||||
get "/latest", headers: headers("fr")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/fr.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("fr")
|
||||
expect(I18n.locale.to_s).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE)
|
||||
end
|
||||
end
|
||||
@ -1140,7 +1142,7 @@ RSpec.describe ApplicationController do
|
||||
it "uses the user's preferred locale" do
|
||||
get "/latest", headers: headers("fr")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/fr.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("fr")
|
||||
end
|
||||
|
||||
it "serves a 404 page in the preferred locale" do
|
||||
@ -1153,7 +1155,7 @@ RSpec.describe ApplicationController do
|
||||
it "serves a RenderEmpty page in the preferred locale" do
|
||||
get "/u/#{user.username}/preferences/interface"
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).to have_tag("script", with: { src: "/assets/locales/fr.js" })
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("fr")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1166,7 +1168,7 @@ RSpec.describe ApplicationController do
|
||||
|
||||
get "/latest", headers: headers("zh-CN")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/zh_CN.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("zh_CN")
|
||||
end
|
||||
end
|
||||
|
||||
@ -1177,7 +1179,7 @@ RSpec.describe ApplicationController do
|
||||
|
||||
get "/latest", headers: headers("")
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("en")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1194,7 +1196,7 @@ RSpec.describe ApplicationController do
|
||||
it "uses the locale from the cookie" do
|
||||
get "/latest", headers: { Cookie: "locale=es" }
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/es.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("es")
|
||||
expect(I18n.locale.to_s).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE) # doesn't leak after requests
|
||||
end
|
||||
end
|
||||
@ -1203,7 +1205,7 @@ RSpec.describe ApplicationController do
|
||||
it "returns the locale and region separated by an underscore" do
|
||||
get "/latest", headers: { Cookie: "locale=zh-CN" }
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/zh_CN.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("zh_CN")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1215,7 +1217,7 @@ RSpec.describe ApplicationController do
|
||||
|
||||
get "/latest", headers: { Cookie: "" }
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("en")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1232,7 +1234,7 @@ RSpec.describe ApplicationController do
|
||||
it "uses the locale from the param" do
|
||||
get "/latest?lang=es"
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/es.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("es")
|
||||
expect(I18n.locale.to_s).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE) # doesn't leak after requests
|
||||
end
|
||||
end
|
||||
@ -1241,7 +1243,7 @@ RSpec.describe ApplicationController do
|
||||
it "returns the locale and region separated by an underscore" do
|
||||
get "/latest?lang=zh-CN"
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/zh_CN.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("zh_CN")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1253,7 +1255,7 @@ RSpec.describe ApplicationController do
|
||||
|
||||
get "/latest"
|
||||
expect(response.status).to eq(200)
|
||||
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
|
||||
expect(main_locale_scripts(response.body)).to contain_exactly("en")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user