@heruan commented on Mon Jul 11 2016
The CompositionContext
interface has viewModel
defined as:
/**
* The view model url or instance for the component.
*/
viewModel?: any;
but if it's set to a view model instance when using Webpack, I get this error:
Uncaught (in promise) TypeError: Cannot read property 'endsWith' of undefined(โฆ)
convertOriginToViewUrl @ aurelia-templating.js:705
ConventionalViewStrategy @ aurelia-templating.js:563
createFallbackViewStrategy @ aurelia-templating.js:700
getViewStrategy @ aurelia-templating.js:691
(anonymous function) @ aurelia-templating.js:4367
because viewModel
seems assumed to be a string.
To reproduce simply use this as main.js
in skeleton-esnext-webpack:
import {bootstrap} from 'aurelia-bootstrapper-webpack';
import {App} from "./app";
bootstrap((aurelia) => {
aurelia.use.standardConfiguration().developmentLogging();
aurelia.start().then(() => aurelia.setRoot( aurelia.container.get(App), document.body) );
});
This happens using Webpack only, the same logic in skeleton-esnext works as expected.
@EisenbergEffect commented on Mon Jul 11 2016
I believe this is a limitation in Webpack due to the fact that it doesn't function as a true module loader.
@niieani Can you look into this please? This issue has come up repeatedly. Either there's a bug in the Webpack loader or this just isn't possible with Webpack. If it isn't possible, we need to include documentation.
@heruan As a workaround, you can always provide the module id. Another possibility would be to manually associate the module id with the view model like so
import {Origin} from 'aurelia-metadata';
export class MyClass {
}
Origin.set(MyClass, new Origin('./my-class', 'MyClass'));
If you need, you could create a decorator to do this as well, potentially leveraging the module id constants that Webpack makes available. I believe it's module.id
but I'm not sure. @niieani can confirm. So, you could do something like this:
function origin(id, name) {
return function(target) {
Origin.set(target.constructor, new Origin(id, name || 'Default'));
}
}
@origin(module.id)
export class MyClass {
}
@heruan commented on Mon Jul 11 2016
Thank you @EisenbergEffect, I hit this also when mapping a route in the router with moduleId
set to an external module such as "module-name": using Webpack it fails with Error: Cannot find module './module-name'
, whereas using JSPM it loads the first export in "module-name" as expected.
Thus, since I'm trying to set view models from external modules as app root and routes, I don't think the Origin
workaround could work.
@EisenbergEffect commented on Mon Jul 11 2016
For the routing scenario, I'm not sure how that would work with Webpack. @niieani will have to chime in on that.
@niieani commented on Mon Jul 11 2016
There are no limitations related to Webpack. When using either external resources/modules or paths to modules that cannot be statically analyzed you need to include them in build resources (see the readme of webpack skeleton and webpack-plugin for more info on how to do that).
The cited error however looks like a bug. I will investigate. Essentially, everything that works with JSPM or RequireJS should work exactly the same with Webpack assuming proper configuration.
@EisenbergEffect commented on Mon Jul 11 2016
@niieani Thanks! That's good to hear. I know you've got plenty you are working on but if you could add this to your list to investigate, that would be great. I've seen this and similar issues come up a few times.
@heruan commented on Mon Jul 11 2016
Thank you @niieani!
For reference, these are a couple of use cases which fails using Webpack but works with JSPM.
- Using an actual module id instead of relative path in
RouteConfig.moduleId
:
routerConfiguration.mapRoute( { route: '/list', moduleId: 'my-module/list' } );
- Using a VM instance in
CompositionContext
, instead of a string:
// in main configure/bootstrap function
let root = aurelia.container.get(MyApp);
aurelia.setRoot(root, document.body);
@niieani commented on Mon Jul 11 2016
Using an actual module id instead of relative path
@heruan This should work, providing you declare the given moduleId as a build resource in your package.json.
The second issue seems to be with Origin metadata not being set properly for the modules by the webpack loader. This is the one I need to investigate.
@heruan commented on Mon Jul 11 2016
Thank you @niieani I can confirm that declaring modules in package.json/aurelia/build/resources
works! I look forward on your investigation for the other case, consider me available for testing.