DEV: Introduce minification and source maps for Theme JS (#18646)

Theme javascript is now minified using Terser, just like our core/plugin JS bundles. This reduces the amount of data sent over the network.

This commit also introduces sourcemaps for theme JS. Browser developer tools will now be able show each source file separately when browsing, and also in backtraces.

For theme test JS, the sourcemap is inlined for simplicity. Network load is not a concern for tests.
This commit is contained in:
David Taylor
2022-10-18 18:20:10 +01:00
committed by GitHub
parent e23b247690
commit be3d6a56ce
14 changed files with 338 additions and 67 deletions

View File

@ -8,28 +8,28 @@ RSpec.describe ThemeJavascriptCompiler do
template = "<h1>hello</h1>"
name = "/path/to/templates1"
compiler.append_raw_template("#{name}.raw", template)
expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}\"")
expect(compiler.raw_content.to_s).to include("addRawTemplate(\"#{name}\"")
name = "/path/to/templates2"
compiler.append_raw_template("#{name}.hbr", template)
expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}\"")
expect(compiler.raw_content.to_s).to include("addRawTemplate(\"#{name}\"")
name = "/path/to/templates3"
compiler.append_raw_template("#{name}.hbs", template)
expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}.hbs\"")
expect(compiler.raw_content.to_s).to include("addRawTemplate(\"#{name}.hbs\"")
end
end
describe "#append_ember_template" do
it 'maintains module names so that discourse-boot.js can correct them' do
compiler.append_ember_template("/connectors/blah-1", "{{var}}")
expect(compiler.content.to_s).to include("define(\"discourse/theme-1/connectors/blah-1\", [\"exports\", \"@ember/template-factory\"]")
expect(compiler.raw_content.to_s).to include("define(\"discourse/theme-1/connectors/blah-1\", [\"exports\", \"@ember/template-factory\"]")
compiler.append_ember_template("connectors/blah-2", "{{var}}")
expect(compiler.content.to_s).to include("define(\"discourse/theme-1/connectors/blah-2\", [\"exports\", \"@ember/template-factory\"]")
expect(compiler.raw_content.to_s).to include("define(\"discourse/theme-1/connectors/blah-2\", [\"exports\", \"@ember/template-factory\"]")
compiler.append_ember_template("javascripts/connectors/blah-3", "{{var}}")
expect(compiler.content.to_s).to include("define(\"discourse/theme-1/javascripts/connectors/blah-3\", [\"exports\", \"@ember/template-factory\"]")
expect(compiler.raw_content.to_s).to include("define(\"discourse/theme-1/javascripts/connectors/blah-3\", [\"exports\", \"@ember/template-factory\"]")
end
end
@ -39,22 +39,22 @@ RSpec.describe ThemeJavascriptCompiler do
compiler = ThemeJavascriptCompiler.new(1, 'marks')
compiler.append_ember_template("connectors/outlet/blah-1", "{{var}}")
compiler.append_module("console.log('test')", "connectors/outlet/blah-1")
expect(compiler.content.to_s).to include("discourse/theme-1/connectors/outlet/blah-1")
expect(compiler.content.to_s).to include("discourse/theme-1/templates/connectors/outlet/blah-1")
expect(compiler.raw_content.to_s).to include("discourse/theme-1/connectors/outlet/blah-1")
expect(compiler.raw_content.to_s).to include("discourse/theme-1/templates/connectors/outlet/blah-1")
# Colocated under `/templates/connectors`
compiler = ThemeJavascriptCompiler.new(1, 'marks')
compiler.append_ember_template("templates/connectors/outlet/blah-1", "{{var}}")
compiler.append_module("console.log('test')", "templates/connectors/outlet/blah-1")
expect(compiler.content.to_s).to include("discourse/theme-1/connectors/outlet/blah-1")
expect(compiler.content.to_s).to include("discourse/theme-1/templates/connectors/outlet/blah-1")
expect(compiler.raw_content.to_s).to include("discourse/theme-1/connectors/outlet/blah-1")
expect(compiler.raw_content.to_s).to include("discourse/theme-1/templates/connectors/outlet/blah-1")
# Not colocated
compiler = ThemeJavascriptCompiler.new(1, 'marks')
compiler.append_ember_template("templates/connectors/outlet/blah-1", "{{var}}")
compiler.append_module("console.log('test')", "connectors/outlet/blah-1")
expect(compiler.content.to_s).to include("discourse/theme-1/connectors/outlet/blah-1")
expect(compiler.content.to_s).to include("discourse/theme-1/templates/connectors/outlet/blah-1")
expect(compiler.raw_content.to_s).to include("discourse/theme-1/connectors/outlet/blah-1")
expect(compiler.raw_content.to_s).to include("discourse/theme-1/templates/connectors/outlet/blah-1")
end
end
@ -83,8 +83,8 @@ RSpec.describe ThemeJavascriptCompiler do
"discourse/templates/components/mycomponent.hbs" => "{{my-component-template}}"
}
)
expect(compiler.content).to include('define("discourse/theme-1/components/mycomponent"')
expect(compiler.content).to include('define("discourse/theme-1/discourse/templates/components/mycomponent"')
expect(compiler.raw_content).to include('define("discourse/theme-1/components/mycomponent"')
expect(compiler.raw_content).to include('define("discourse/theme-1/discourse/templates/components/mycomponent"')
end
it "handles colocated components" do
@ -97,8 +97,8 @@ RSpec.describe ThemeJavascriptCompiler do
"discourse/components/mycomponent.hbs" => "{{my-component-template}}"
}
)
expect(compiler.content).to include("__COLOCATED_TEMPLATE__ =")
expect(compiler.content).to include("setComponentTemplate")
expect(compiler.raw_content).to include("__COLOCATED_TEMPLATE__ =")
expect(compiler.raw_content).to include("setComponentTemplate")
end
it "prints error when default export missing" do
@ -111,8 +111,8 @@ RSpec.describe ThemeJavascriptCompiler do
"discourse/components/mycomponent.hbs" => "{{my-component-template}}"
}
)
expect(compiler.content).to include("__COLOCATED_TEMPLATE__ =")
expect(compiler.content).to include("throw new Error")
expect(compiler.raw_content).to include("__COLOCATED_TEMPLATE__ =")
expect(compiler.raw_content).to include("throw new Error")
end
it "handles template-only components" do
@ -121,9 +121,35 @@ RSpec.describe ThemeJavascriptCompiler do
"discourse/components/mycomponent.hbs" => "{{my-component-template}}"
}
)
expect(compiler.content).to include("__COLOCATED_TEMPLATE__ =")
expect(compiler.content).to include("setComponentTemplate")
expect(compiler.content).to include("@ember/component/template-only")
expect(compiler.raw_content).to include("__COLOCATED_TEMPLATE__ =")
expect(compiler.raw_content).to include("setComponentTemplate")
expect(compiler.raw_content).to include("@ember/component/template-only")
end
end
describe "terser compilation" do
it "applies terser and provides sourcemaps" do
sources = {
"multiply.js" => "let multiply = (firstValue, secondValue) => firstValue * secondValue;",
"add.js" => "let add = (firstValue, secondValue) => firstValue + secondValue;"
}
compiler.append_tree(sources)
expect(compiler.content).to include("multiply")
expect(compiler.content).to include("add")
map = JSON.parse(compiler.source_map)
expect(map["sources"]).to contain_exactly(*sources.keys)
expect(map["sourcesContent"].to_s).to include("let multiply")
expect(map["sourcesContent"].to_s).to include("let add")
expect(map["sourceRoot"]).to eq("theme-1/")
end
it "handles invalid JS" do
compiler.append_raw_script("filename.js", "if(someCondition")
expect(compiler.content).to include('console.error("[THEME 1')
expect(compiler.content).to include('Unexpected token')
end
end
end