How to ship javascript library with plugin?

Hi,
I’d like to ask what is recommended way to ship javascript library with some plugin? I can load it asynchronously from external url using e.g.

Em.$.getScript('https://cdnjs.cloudflare.com/ajax/libs/......min.js').done(function() {
...
}

But I’d prefer storing library locally. Normally I’d use vendor.js to include it and have it loaded before the plugin code, but this approach needs hacking with the Discourse core… So what is recommended way and where to add external js library to plugin? Is there some convention? Thx.

Just add the js lib at the assets folder in your plugin, or if available, as a gem dependency.

2 Likes

Thanks… In the assets folder will it be loaded automatically or do I need to take care of asynchronous load as quoted in previous post? I need to load library before running plugin code.

It’s loaded in the plugin-third-party file, inside the HEAD. You can use ES6 modules to require stuff.

1 Like

I asked a similar question a few days ago (Existing JS module import into ES6 plugin). The problem I have is, that I want it included server side and I have no idea on which path I should require it in ES6 modules.

Got back to you there, so we don’t pollute here.

Thanks… placing js lib in asset folder and register_asset in plugin.rb did the trick.

2 Likes

Sorry for necroing this thread, but this is where Google has brought me. I’ve been trying for a couple of hours to get a JS library to load inside my plugin.

  • In my app’s assets/javascripts folder, I have a file named argdown-core.js.
  • In my plugin.rb file, I’m doing register_asset 'javascripts/argdown-core.js'.
  • In assets/javascripts/discourse-markdown/argdown.js.es6, I’m doing import { argdown } from "argdown-core.js".

I’ve tried lots of variations on the above and I keep getting Uncaught Error: Could not find module argdown-core.js imported from discourse/plugins/Argdown/discourse-markdown/argdown.

Some of the things I’ve tried:

  • Moving the file into various folders
  • Lots of permutations on the import line
  • Putting .es6 on the file extension - other JS files seem to need that to run
  • Putting :server_side at the end of my register_asset line in plugin.rb, since that’s where this should run
  • Looking for other plugins that require third-party libraries - can’t find any that use strategies I’m not using
  • Digging through Discourse’s code to try to understand the bundling system

This is probably simple and there’s something obvious I’m missing. Can anyone help?

1 Like

https://github.com/discourse/discourse-algolia is doing this for example, I recommend you have a look at the code, especially top of plugin.rb.

Also a small tip, in programming things always seem hard when you feel like you don’t know the effects of your actions, it’s important to know what’s going on, I recommend running this command in your console: window.requirejs.entries it might help you understand a few things.

5 Likes

Thank you, that’s very helpful! Putting my library in the assets/lib folder is helping a lot.

Now that I have the correct path to it, the library is misbehaving. :man_facepalming: It’s a large library with lots of submodules - argdown.js requires ArgdownApplication.js and a bunch of others. When it tries to load ArgdownApplication.js it says “Uncaught ReferenceError: exports is not defined.”

I’ve tried bundling the whole thing into one file using Webpack, but for some reason the bundle is missing a third-party library called “punycode”. I’ve tried adding punycode into the compiled module, I’ve tried uploading it to the lib folder and adding register_asset 'lib/punycode.js' to plugin.rb, and I’m not having much luck.

The library works on my computer and in another plugin I’ve written. Is there a recommended way to add an NPM module to a Discourse plugin? This thread says to copy the module’s folder into your /lib/ folder; that’s not working for me.* Can you point me to an example of someone successfully shipping a complex NPM module with a Discourse plugin so I can see what I’m doing wrong?

*In that thread they’re trying to load the module remotely from unpkg.com; I’d rather do it locally, although maybe I should try that.

1 Like

I recommend you go with the fully packaged solution.

1 Like