FEATURE: Plugin support for transpiling regular `.js` files (#9398)

FEATURE: Plugin support for transpiling regular .js files (#9398)

This adds support for a new piece of metadata to your plugin.rb files. If you add:

transpile_js: true

Then Discourse will support transpilation of assets in your assets/javascripts directory. Previously they had to be named .js.es6 but now regular .js will work.

Note this is opt-in because some plugins currently have .js files in app/assets that are not meant to be transpiled.

Going forward all plugins should migrate to this setting as they are comfortable able to do so.

diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb
index 7417207..6d56af7 100644
--- a/lib/discourse_js_processor.rb
+++ b/lib/discourse_js_processor.rb
@@ -4,6 +4,10 @@ require 'mini_racer'
 
 class DiscourseJsProcessor
 
+  def self.plugin_transpile_paths
+    @@plugin_transpile_paths ||= Set.new
+  end
+
   def self.call(input)
     root_path = input[:load_path] || ''
     logical_path = (input[:filename] || '').sub(root_path, '').gsub(/\.(js|es6).*$/, '').sub(/^\//, '')
@@ -56,6 +60,8 @@ class DiscourseJsProcessor
       embed-application
     ).any? { |f| relative_path == "#{js_root}/#{f}.js" }
 
+    return true if plugin_transpile_paths.any? { |prefix| relative_path.start_with?(prefix) }
+
     !!(relative_path =~ /^#{js_root}\/[^\/]+\// ||
       relative_path =~ /^#{test_root}\/[^\/]+\//)
   end
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index 2510e6c..85f06df 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -66,6 +66,13 @@ class Plugin::Instance
     }
   end
 
+  # If plugins provide `transpile_js: true` in their metadata we will
+  # transpile regular JS files in the assets folders. Going forward,
+  # all plugins should do this.
+  def transpile_js
+    metadata.try(:transpile_js) == "true"
+  end
+
   def seed_data
     @seed_data ||= HashWithIndifferentAccess.new({})
   end
@@ -511,16 +518,22 @@ class Plugin::Instance
   def activate!
 
     if @path
+      root_dir_name = File.dirname(@path)
+
       # Automatically include all ES6 JS and hbs files
-      root_path = "#{File.dirname(@path)}/assets/javascripts"
+      root_path = "#{root_dir_name}/assets/javascripts"
       DiscoursePluginRegistry.register_glob(root_path, 'js.es6')
       DiscoursePluginRegistry.register_glob(root_path, 'hbs')
       DiscoursePluginRegistry.register_glob(root_path, 'hbr')
 
-      admin_path = "#{File.dirname(@path)}/admin/assets/javascripts"
+      admin_path = "#{root_dir_name}/admin/assets/javascripts"
       DiscoursePluginRegistry.register_glob(admin_path, 'js.es6', admin: true)
       DiscoursePluginRegistry.register_glob(admin_path, 'hbs', admin: true)
       DiscoursePluginRegistry.register_glob(admin_path, 'hbr', admin: true)
+
+      if transpile_js
+        DiscourseJsProcessor.plugin_transpile_paths << root_path.sub(Rails.root.to_s, '').sub(/^\/*/, '')
+      end
     end
 
     self.instance_eval File.read(path), path
@@ -663,9 +676,12 @@ class Plugin::Instance
       root_path = "#{File.dirname(@path)}/assets/javascripts"
 
       Dir.glob("#{root_path}/**/*") do |f|
+        f_str = f.to_s
         if File.directory?(f)
           yield [f, true]
-        elsif f.to_s.ends_with?(".js.es6") || f.to_s.ends_with?(".hbs") || f.to_s.ends_with?(".hbr")
+        elsif f_str.ends_with?(".js.es6") || f_str.ends_with?(".hbs") || f_str.ends_with?(".hbr")
+          yield [f, false]
+        elsif transpile_js && f_str.ends_with?(".js")
           yield [f, false]
         end
       end
diff --git a/lib/plugin/metadata.rb b/lib/plugin/metadata.rb
index 5ceabfd..1af6c15 100644
--- a/lib/plugin/metadata.rb
+++ b/lib/plugin/metadata.rb
@@ -78,7 +78,7 @@ class Plugin::Metadata
     "discourse-internet-explorer"
   ])
 
-  FIELDS ||= [:name, :about, :version, :authors, :url, :required_version]
+  FIELDS ||= [:name, :about, :version, :authors, :url, :required_version, :transpile_js]
   attr_accessor(*FIELDS)
 
   def self.parse(text)

GitHub sha: 7b4fdebb

1 Like

This commit appears in #9398 which was merged by eviltrout.