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) => {
const name = directory.name;
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 hasJs = fs.existsSync(jsDirectory);
const hasAdminJs = fs.existsSync(adminJsDirectory);
const hasTests = fs.existsSync(testDirectory);
return { name, jsDirectory, testDirectory, hasJs, hasTests };
return {
name,
jsDirectory,
adminJsDirectory,
testDirectory,
hasJs,
hasAdminJs,
hasTests,
};
});
},
generatePluginsTree() {
const appTree = this._generatePluginAppTree();
const testTree = this._generatePluginTestTree();
return mergeTrees([appTree, testTree]);
const adminTree = this._generatePluginAdminTree();
return mergeTrees([appTree, testTree, adminTree]);
},
_generatePluginAppTree() {
const trees = this.pluginInfos()
.filter((p) => p.hasJs)
.map(({ name, jsDirectory }) => {
let tree = new WatchedDir(jsDirectory);
tree = fixLegacyExtensions(tree);
tree = unColocateConnectors(tree);
tree = namespaceModules(tree, name);
tree = RawHandlebarsCompiler(tree);
tree = this.compileTemplates(tree);
tree = this.processedAddonJsFiles(tree);
return concat(mergeTrees([tree]), {
inputFiles: ["**/*.js"],
.map(({ name, jsDirectory }) =>
this._buildAppTree({
directory: jsDirectory,
pluginName: name,
outputFile: `assets/plugins/${name}.js`,
allowNone: true,
});
});
})
);
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() {
const trees = this.pluginInfos()
.filter((p) => p.hasTests)

View File

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

View File

@ -382,7 +382,7 @@ module Discourse
def self.find_plugin_js_assets(args)
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
plugins = apply_asset_filters(plugins, :js, args[:request])
@ -391,6 +391,8 @@ module Discourse
assets = []
assets << "plugins/#{plugin.directory_name}" if plugin.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
end
end

View File

@ -862,6 +862,15 @@ class Plugin::Instance
EmberCli.plugin_assets? && File.exist?(extra_js_file_path)
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:
# 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.