I want to intercept the module loading of Aurelia to redirect some calls.
To do such things the aurelia-loader has a addPlugin() interface. You add a suffix like !myplugin to a resource to mark that it should be loaded using that plugin.
Now when I do this with my own component, it loads the JS file but the name for the HTML template is messed up. Like from the resource name my-comp!myplugin it will load my-comp.js but tries to find my-comp!myplugin.html which does not match the plugin name anymore.
I have provided a gist with that issue here: https://gist.run/?id=c7ed477bc652540ed8b0702d843f1832
The loader plugin code in main.js is basically:
loader.addPlugin('gate', {
fetch(address) {
console.info('Intercepted:', address);
var tmpParts = address.split('.');
var extension = tmpParts[tmpParts.length - 1].toLowerCase();
if (extension == 'css') {
console.debug('Loading as styles', address);
return loader.loadText(address);
} else if(extension == 'html') {
console.debug('Loading as template:', address);
return loader.loadTemplate(address);
} else {
console.debug('Loading as module:', address);
return loader.loadModule(address);
}
}
});
Using it like this in a template (marked with Issue 1 in the gist):
<require from="./comp2!gate"></require>
After that is should be possible to load the component like this:
<comp2></comp2>
Or even like this:
<compose view-model="./comp2!gate"></compose>
Instead the name for the template is messed up, the browser console says:
Failed to load resource: the server responded with a status of 404 ()
The expected name of the template would be https://gist.host/run/1485182959149/comp2.html!gate (including the plugin)
How can I fix the loader plugin to work correctly?
The loader is aurelia-loader-default 1.0.0, JSPM is 0.16.39, Node is 6.5.0, NPM 3.10.5.
I have added a second gist.run: https://gist.run/?id=1ddd4233e3afc40d89eb64b751e1dd8f
It is a bit shorter. When I specify the view using @useView decorator in comp2.js (marked with issue 4), it works - but I cannot specify a loader plugin with @useView. I would expect it to load the view with the same loader plugin or be able to specify a loader plugin with @useView.
Okay, I found a solution which looks like it can work with less code and patching and it works between two gists.
This gist contains the external component comp3:
https://gist.run/?id=dc837978a514011e13c872dbad92ae3f
This gist is the basic Aurelia app with a plugin and a small patch to the applyPluginToUrl method of the loader:
https://gist.run/?id=39e6fdacefc9e5c69b42a5e8c9049384
If the gist URLs are fixed, it should work for everyone. The Aurelia app loads comp3 from the first gist and displays it (you see the purple border define in the comp3-view).
There is one caveat at the moment: No support for CSS as SystemJS adds the extension .js to them, looks like I have to take care of that.
I do not like the path to loader.applyPluginToUrl but SystemJS does not really support plugin chaining and so the order must be correct. Also this solution requires all external components to set @useView including the loader plugin.
Any better approaches?