I thought I got some basic understanding of the 'grand scheme' of the resource registry in Plone 5 in the last 12-18 months. I even dare to write some introduction tutorials for one of our customers, but went down a small rabbit hole last week when I tried to add Highcharts 8 to a Plone 5.2 site.
(Skip the 'digging myself in' part below for some nice workaround in the second part)
[1] Many javascript projects nowadays distribute their work in AMD/loading aware setup: if you load the js files in a simple page or playground it works like Javascript from 2006, but the files are wrapped in smart code: when it detects a require.js setup the only way is the require way. Highcharts has 4-15 different files you can load to compose your required functionality. (highcharts.js, highcharts-more.js, exporting.js, export-data.js and accessibilty.js in my case).
My first hunch was to create IResourceRegistry entries for each of these files from the Highcharts package. I had put the files from highcharts in a subdirectory in my add'on and registered/published them in the url namespace using zcml to ++resource++my.highcharts.addon/
After that I created an IBundleRegistry with those I resources and hope/expect that everything gets compiled into a ++plone++my.highcharts.addon/highcharts.compiled.min.js file (where I registered "my.highcharts.addon as a ++plone++ resource in my add'on package for highcharts.
bin/plone-compile-resources -s myPlone -b highcharts
should then create/compile my bundle to filesystem and/or should write it in a subdirectory of portal_resources in the ZODB when I develop the bundle from the resource registry control panel.
First try seemed to work, but upon closer inspection and when I started changing parameters in the resource registry everything broke down real quick: plone-compile-resources was creating new javascript files in my add'on's mappped ++reource++ directory for the individual IResource. So highcharts.js got a highcharts.compiled.js next to it, a highcharts-more.compiled.js. was created, etc.
Why is this happening? I expect the compilation phase to modify something at the paths configured in the bundle for the jscompilation and csscompilation variables, but never touch individual IReources: they should be served 1:1 when I enable development mode in the resource registry and develop individual bundles's js and otherwise they should be included in a compiled/minified mybundle.js .
I have many more smaller questions and maybe the first answers I'll get are *"it depends on your settings for compile=True etc in the IBundleRegistry configuration". IMHO IResources should never be manipulated/compiled or whatever into new files, independent of Bundle's settings where they get attache to as a resource. So I'm not understanding something here.
[2] When I was out of the rabbit hole: the tricks I used.
In this case my naive thought of bundling the files Highcharts wants in a single js was flawed anyway, because the 'correct' way of getting highcharts in a html-based page is using require.js its packages functionality.
(I had similar issues last year with loading a plugin for jQuery. One has to use require(['jquery','path-to-myplugin'] and then some setup code to get a handle to the 'master' jquery to register your plugin onto, if you just load the plugin.js code directly it's async roulettte if it can find $. )
Trick 1: you can stack multiple require.config calls and it will update the browser site require.js registry, you don't HAVE to have your resources in the config.js which Plone serves right after require.js gets loaded on a page.
So I now have one .js file with this top part:
require.config({
packages: [{
name: 'highcharts',
main: 'highcharts'
}],
paths: {
// Change this to your server if you do not wish to use our CDN.
'highcharts': '++resource++highcharts/',
'domReady': '++resource++my.highcharts.addon/domReady'
}
});
It is loaded from one IBundleRegistry entry in the Resource registry and adds highcharts and a useful require.js plugin domReady. (I first tried to register the single domReady plugin in Plone's config.js for require.js and even that was a fail.).
Trick 2: you can inspect the require.js configuration after a page has loaded in the the developer tools of your browser by calling requirejs.s.contexts._.config
from the console.
With this in place I can add my custom javascript after the extra require.config part to activate higcharts on links to 'graph' content items in the main Text on a Document like this:
require([
"jquery"
"domReady",
"highcharts",
"highcharts/modules/exporting",
"highcharts/modules/export-data",
"highcharts/modules/accessibility",
], function ($, domReady, Highcharts) {
domReady(function () {
$("div[class*='graphlink'] a").each(function (index) {
// lots of custom code to fetch the chart configuration
And everything is finally loading without errors, undefined's or whatevers, independento of loading errors. Mission accomplished with work arounds, using require.js but skipping the resource registry.
[3] Rant:
To get out of descent into the rabbit hole I started modifying variables in the resource registry bundle and very quickly broke all the javascript in my Plone site. There were in hindsight misleading javascript errors in the console saying 'Highcharts cannot be loaded in javascript-file.compiled.js' where javascript-compiled.js' was nowhere to be found on the Network tab in the browser of loaded js files. Clicking on details of the error showed a 'page cannot be loaded. Huh?
Backtracking I think my custom javascript mess got into the bundle and then 'combined' in the plone.default.js production bundle. The browser downloaded a generated .map for my bundle and looked up and showed the never loaded source javascript file from there to help me push me furhter down.