framework
framework copied to clipboard
Make resources receivable from external repositories/cdn's etc
I'm submitting a bug report
- Library Version: 1.0.2
Please tell us about your environment:
-
Operating System: Windows 10
-
Node Version: 4.6.0
- NPM Version: 3.10.10
- JSPM OR Webpack AND Version aurelia cli
-
Browser: all
-
Language: all
Current behavior: External resources (i. e. custom elements) cannot be referenced. If I try to reference a custom element from here:
config.globalResources(["https://www.cdn-intranet.com/resources/elements/test-stuff"]);
it tries to resolve the url "as-is" and does not try to resolve it for ".js" and ".html". In fact, it tries to resolve https://www.cdn-intranet.com/resources/elements/test-stuff
and received a 404. I also tried
config.globalResources(["//www.cdn-intranet.com/resources/elements/test-stuff"]);
but it doesn't work, too.
Expected/desired behavior: It would be neat if aurelia would not make a difference between locally or externally available resources.
- What is the motivation / use case for changing the behavior? We are serving 60.000 employees across the world. Saving and optimizing bandwith is important to us. Custom elements like grids, tables, layout stuff etc. do not change and are equally implemented in all our applications. Deploying these custom elements on a loadbalanced web server ensures that browsers cache these elements across all our 400 applications. We are actually doing this with our current knockout-based framework, too, and works perfectly.
I think this is probably supported by the requirejs loader used by aurelia cli projects.
Try adding the following to the top of your main.js
:
// add this: (don't worry, requirejs is in the global scope)
requirejs.config({
packages: [
{
name: 'test-stuff',
location: 'https://www.cdn-intranet.com/resources/elements/test-stuff',
main: 'index'
}
});
export function configure(aurelia: Aurelia) {
aurelia.use
.standardConfiguration()
.plugin('test-stuff') // <------- also add this
.feature('resources');
Next, make sure you have an index.js
at https://www.cdn-intranet.com/resources/elements/test-stuff/index.js that contains the transpiled version of this code:
export function configure(config) {
config.globalResources([
'./upper-value-converter',
// other stuff .....
]);
}
Last but not least, make sure you have a transpiled upper-value-converter.js
at https://www.cdn-intranet.com/resources/elements/test-stuff/upper-value-converter.js
I've tried something similar but actually it works for js files only (perfectly for a value-converter). But if you try to load a custom component you need to have the html file loaded as well.
My Custom Component is called test-stuff. So what's happening -> require loads the index.js from a remote server as expected. Then the js file of the custom component (./test-stuff) is loaded from the remote server. This is working as expected, too. But then I receive this error:
Uncaught TypeError: h.load is not a function (This error appears about 1,5 seconds before the next one)
Unhandled rejection Error: Load timeout for modules: template-registry-entry!test-stuff/test-stuff.html_unnormalized2,template-registry-entry!test-stuff/test-stuff.html,text!test-stuff/test-stuff.html_unnormalized3,text!test-stuff/test-stuff.html http://requirejs.org/docs/errors.html#timeout
One interesting thing though: In the network tab of the browser I can see that it doesn't even try to load the html file.
ok getting close- would you be able to debug this and make a determination where things are going wrong in the loader?
Yes. I need to download the debug version of require though. This minified version is not very handy for debugging. Back in a few... :-)
It fails at this point here (in requirejs):
plugin.load(map.name, localRequire, load, config);
Parameter map.name
is "remoteStuff/test-stuff.html".
Via aurelia-loader-default
it tries to load the template:
TextTemplateLoader.prototype.loadTemplate = function loadTemplate(loader, entry) {
return loader.loadText(entry.address).then(function (text) {
entry.template = _aureliaPal.DOM.createTemplateFromMarkup(text);
});
};
entry.address
is "remoteStuff/test-stuff.html". Which is wrong. It is supposed to be a remote address.
this is my require config:
requirejs.config({
packages: [
{
name: 'remoteStuff',
location: 'https://myInternalCDN.de/app/componentstore/aurelia/elements/test-stuff',
main: 'index'
}
]
});
aurelia config:
aurelia.use
.standardConfiguration()
.plugin("remoteStuff")
.feature('resources');
transpiled version of "https://myInternalCDN.de/app/componentstore/aurelia/elements/test-stuff/index.js"
define('remoteStuff',["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function configure(config) {
config.globalResources(["./test-stuff"]);
}
exports.configure = configure;
});
Are there any news yet? Can you work the debug information I've provided or do you need something else?
@DamageLimiter it would be awesome if you could continue to attack this one. Why isn't the module loader replacing the remoteStuff
part of remoteStuff/test-stuff.html
with the full url from the configuration?
In the meantime, what happens if you do something like this:
main.js:
import {TestTemplateLoader} from 'aurelia-loader-default'; // double check this import- I wrote this from memory
TextTemplateLoader.prototype.loadTemplate = function loadTemplate(loader, entry) {
entry.address = entry.address.replace(/^remoteStuff\//, 'https://myInternalCDN.de/app/componentstore/aurelia/elements/test-stuff');
return loader.loadText(entry.address).then(function (text) {
entry.template = _aureliaPal.DOM.createTemplateFromMarkup(text);
});
};
export function configure(aurelia) {
...
...
...
This kind of test ^^^ will tell us if there are any further roadblocks after we get the entry address fixed. It may also serve as a temporary workaround for you.
@jdanyow @EisenbergEffect We encounter the same Uncaught TypeError: h.load is not a function
error quite often, and it isn't telling us what is going wrong. It is only in CLI projects using es2015.
It would be nice to have a better error message, but I can't seem to figure out where in Aurelia/the cli that needs a change.
- For missing/misspelled .html files it throws the error
- Sometimes you'll get the same error when adding plugins to the bundle in
aurelia.json
. I can't remember the specific scenario.
This missing error description is really a pain, and it often comes up in gitter as well.
@stsje h.load
is the minified version of plugin.load
(see me debug information) thus the error is thrown in requirejs. At the bottom line is more or a less a file not found
or reference unknown
error.
@jdanyow I'll dig in debugging the hell out of this. Once I identified the culprit I'll let you know ;-)
@DamageLimiter Did you guys ever figure out a solution for this? My team is looking to do something similar and I'm curious how you resolved the issue.
Hi @rdelhommer, I put together a quick demo project of how I handle loading external plugins and libraries for external use. I have to do an extra step of bundling the plugins I want to use via a CDN but it works just fine. The sample project demos how you could bring in the aurelia-dialog plugin externally. I use this approach for FrontEnd Creator which is an online tool used to author Aurelia applications. https://github.com/mattduffield/au-cdn