FIX: Load admin-specific JS when compiling via ember-cli (#18086)

The previous sprockets implementation was including admin-specific JS in the plugin's main JS file, which would be served to all users regardless of admin status. This commit achieves the same result under the ember-cli plugin asset compiler with one difference: the admin js is compiled into a separate file. That means that in future, we'll be able to make it loaded only for admins. For now though, it's loaded for everyone, just like before.
This commit is contained in:
David Taylor 2022-08-25 11:36:02 +01:00 committed by GitHub
parent e141208605
commit 9ebebfb4cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 23 deletions

View File

@ -78,43 +78,79 @@ module.exports = {
return pluginDirectories.map((directory) => { return pluginDirectories.map((directory) => {
const name = directory.name; const name = directory.name;
const jsDirectory = path.resolve(root, name, "assets/javascripts"); const jsDirectory = path.resolve(root, name, "assets/javascripts");
const adminJsDirectory = path.resolve(
root,
name,
"admin/assets/javascripts"
);
const testDirectory = path.resolve(root, name, "test/javascripts"); const testDirectory = path.resolve(root, name, "test/javascripts");
const hasJs = fs.existsSync(jsDirectory); const hasJs = fs.existsSync(jsDirectory);
const hasAdminJs = fs.existsSync(adminJsDirectory);
const hasTests = fs.existsSync(testDirectory); const hasTests = fs.existsSync(testDirectory);
return { name, jsDirectory, testDirectory, hasJs, hasTests }; return {
name,
jsDirectory,
adminJsDirectory,
testDirectory,
hasJs,
hasAdminJs,
hasTests,
};
}); });
}, },
generatePluginsTree() { generatePluginsTree() {
const appTree = this._generatePluginAppTree(); const appTree = this._generatePluginAppTree();
const testTree = this._generatePluginTestTree(); const testTree = this._generatePluginTestTree();
return mergeTrees([appTree, testTree]); const adminTree = this._generatePluginAdminTree();
return mergeTrees([appTree, testTree, adminTree]);
}, },
_generatePluginAppTree() { _generatePluginAppTree() {
const trees = this.pluginInfos() const trees = this.pluginInfos()
.filter((p) => p.hasJs) .filter((p) => p.hasJs)
.map(({ name, jsDirectory }) => { .map(({ name, jsDirectory }) =>
let tree = new WatchedDir(jsDirectory); this._buildAppTree({
directory: jsDirectory,
tree = fixLegacyExtensions(tree); pluginName: name,
tree = unColocateConnectors(tree);
tree = namespaceModules(tree, name);
tree = RawHandlebarsCompiler(tree);
tree = this.compileTemplates(tree);
tree = this.processedAddonJsFiles(tree);
return concat(mergeTrees([tree]), {
inputFiles: ["**/*.js"],
outputFile: `assets/plugins/${name}.js`, outputFile: `assets/plugins/${name}.js`,
allowNone: true, })
}); );
});
return mergeTrees(trees); return mergeTrees(trees);
}, },
_generatePluginAdminTree() {
const trees = this.pluginInfos()
.filter((p) => p.hasAdminJs)
.map(({ name, adminJsDirectory }) =>
this._buildAppTree({
directory: adminJsDirectory,
pluginName: name,
outputFile: `assets/plugins/${name}_admin.js`,
})
);
return mergeTrees(trees);
},
_buildAppTree({ directory, pluginName, outputFile }) {
let tree = new WatchedDir(directory);
tree = fixLegacyExtensions(tree);
tree = unColocateConnectors(tree);
tree = namespaceModules(tree, pluginName);
tree = RawHandlebarsCompiler(tree);
tree = this.compileTemplates(tree);
tree = this.processedAddonJsFiles(tree);
return concat(mergeTrees([tree]), {
inputFiles: ["**/*.js"],
outputFile,
allowNone: true,
});
},
_generatePluginTestTree() { _generatePluginTestTree() {
const trees = this.pluginInfos() const trees = this.pluginInfos()
.filter((p) => p.hasTests) .filter((p) => p.hasTests)

View File

@ -386,7 +386,7 @@ module.exports = {
.findAddonByName("discourse-plugins") .findAddonByName("discourse-plugins")
.pluginInfos(); .pluginInfos();
for (const { name, hasJs } of pluginInfos) { for (const { name, hasJs, hasAdminJs } of pluginInfos) {
if (hasJs) { if (hasJs) {
scripts.push({ src: `plugins/${name}.js`, name }); scripts.push({ src: `plugins/${name}.js`, name });
} }
@ -394,16 +394,19 @@ module.exports = {
if (fs.existsSync(`../plugins/${name}_extras.js.erb`)) { if (fs.existsSync(`../plugins/${name}_extras.js.erb`)) {
scripts.push({ src: `plugins/${name}_extras.js`, name }); scripts.push({ src: `plugins/${name}_extras.js`, name });
} }
if (hasAdminJs) {
scripts.push({ src: `plugins/${name}_admin.js`, name });
}
} }
} else { } else {
scripts.push({ scripts.push({
src: "discourse/tests/active-plugins.js", src: "discourse/tests/active-plugins.js",
name: "_all", name: "_all",
}); });
scripts.push({ src: "admin-plugins.js", name: "_admin" });
} }
scripts.push({ src: "admin-plugins.js", name: "_admin" });
return scripts return scripts
.map( .map(
({ src, name }) => ({ src, name }) =>

View File

@ -382,7 +382,7 @@ module Discourse
def self.find_plugin_js_assets(args) def self.find_plugin_js_assets(args)
plugins = self.find_plugins(args).select do |plugin| plugins = self.find_plugins(args).select do |plugin|
plugin.js_asset_exists? || plugin.extra_js_asset_exists? plugin.js_asset_exists? || plugin.extra_js_asset_exists? || plugin.admin_js_asset_exists?
end end
plugins = apply_asset_filters(plugins, :js, args[:request]) plugins = apply_asset_filters(plugins, :js, args[:request])
@ -391,6 +391,8 @@ module Discourse
assets = [] assets = []
assets << "plugins/#{plugin.directory_name}" if plugin.js_asset_exists? assets << "plugins/#{plugin.directory_name}" if plugin.js_asset_exists?
assets << "plugins/#{plugin.directory_name}_extra" if plugin.extra_js_asset_exists? assets << "plugins/#{plugin.directory_name}_extra" if plugin.extra_js_asset_exists?
# TODO: make admin asset only load for admins
assets << "plugins/#{plugin.directory_name}_admin" if plugin.admin_js_asset_exists?
assets assets
end end
end end

View File

@ -862,6 +862,15 @@ class Plugin::Instance
EmberCli.plugin_assets? && File.exist?(extra_js_file_path) EmberCli.plugin_assets? && File.exist?(extra_js_file_path)
end end
def admin_js_asset_exists?
if EmberCli.plugin_assets?
# If this directory exists, ember-cli will output a .js file
File.exist?("#{File.dirname(@path)}/admin/assets/javascripts")
else
false
end
end
# Receives an array with two elements: # Receives an array with two elements:
# 1. A symbol that represents the name of the value to filter. # 1. A symbol that represents the name of the value to filter.
# 2. A Proc that takes the existing ActiveRecord::Relation and the value received from the front-end. # 2. A Proc that takes the existing ActiveRecord::Relation and the value received from the front-end.