Hi,
I'm using the latest version of angular 2 and angular universal and whenever I try to use templateUrl or styleUrls in components I get something like this:
No ResourceLoader implementation has been provided. "file:///Users/.../css/home.css"
No ResourceLoader implementation has been provided. Can't read the url "file:///Users/.../views/home.html"
@pitAlex This is a common problem, and I'm making sure it's documented somewhere on how to properly use those (with Universal).
But basically, you have 2 options :
Either use template instead of _templateUrl_:
template : require('')`
Or better yet, add angular2-template-loader to your webpack configuration, that way you can use both.
More info on it here: https://github.com/TheLarkInn/angular2-template-loader The readme should help you if you run into any issues.
Chain it to your current TS loader, and you'll be able to use both styleUrl & templateUrl
loaders: ['awesome-typescript-loader', 'angular2-template-loader']
Let me know if it doesn't work for you somehow!
Using template like you mentioned, works. Thats how I am doing it now. But I wanted a way to load the css file also into page, and without webpack.
also trying to use that without webpack, any workarounds? thanks.
Do you mean just a regular import "something.css"; ?
What error is that throwing, haven't tried that yet!
Yes, I am using templateUrl with moduleId: module.id to get relative paths, but there's still message No ResourceLoader implementation has been provided.
I manage to get solved with custom build https://github.com/jkuri/ng2-platform-node/blob/master/node-platform.ts#L776-L786 but not so familiar with that project so not sure if that's the right way.
Might have to ask Pat @gdi2290 for guidance on what is missing for SystemJS support, maybe you'd be interested in trying to tackle it? Currently it's webpack only. #283 old system issue
Cool, thanks! Actually I am using this in rollup.
@jkuri can you make a PR with a simple test?
I've found a way to work around this error for now. It's a but of a hack so I would recommend that this isn't the long term solution but it will get people up and running. To make this work you need to add this file
(it's src/app/resource-loader below)
import * as path from 'path';
import * as fs from 'fs';
import {ResourceLoader} from "@angular/compiler";
export class FileSystemResourceLoader extends ResourceLoader {
resolve(url: string, baseUrl: string): string {
//Angular assembles absolute URL's and prefixes them with //
if (url.indexOf("/") !== 0) {
//Resolve relative URL's based on the app root.
return path.join(baseUrl, url);
} else {
return url;
}
}
get(url: string): Promise<string> {
const appDir = path.join(__dirname);
const templatePath = this.resolve(url, appDir);
return new Promise((resolve, reject) => {
fs.readFile(templatePath, 'utf8', (err, data) => {
if(err) {
reject(err);
} else {
resolve(data);
}
})
});
}
}
add these imports
import { FileSystemResourceLoader } from './src/app/resource-loader';
import { ResourceLoader } from '@angular/compiler';
import { platformNodeDynamic } from 'angular2-universal/node';
and add this property to the object which is passed to createEngine
platform: (extraProviders) => {
var platform = platformNodeDynamic(extraProviders);
(<any> platform).cacheModuleFactory_old = platform.cacheModuleFactory;
platform.cacheModuleFactory = (moduleType: any, compilerOptions?: any): Promise<any> => {
if(!compilerOptions) {
compilerOptions = {
providers: [
{provide: ResourceLoader, useClass: FileSystemResourceLoader}
]
}
}
return (<any> platform).cacheModuleFactory_old(moduleType, compilerOptions);
}
return platform;
},
Basically this is intercepting the cache module factory call and adding a compiler options param if there isn't one. The new compiler options contains the ResourceLoader provider which is defined in the first file. The correct solution would either be to supply this resource loader as part of angular-universal or (probably better) allow us to pass in the compiler options as a property so we can do it ourselves.
@waterfoul your patch works just great, thanks!
@waterfoul this patch works great, thanks!
Might seem like a stupid post ( and it probably is ) but for those of you getting the " No ResourceLoader implementation has been provided " error while using the default starter kit with webpack and angular2-template-loader make sure that you don't put any white space between templateUrl and colon
_Example :_
templateUrl : './sometemplate.component.html' <- not good
templateUrl: './sometemplate.component.html' <- good
will be fixed in ng4
https://github.com/angular/angular/issues/13822
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
I've found a way to work around this error for now. It's a but of a hack so I would recommend that this isn't the long term solution but it will get people up and running. To make this work you need to add this file
(it's src/app/resource-loader below)
add these imports
and add this property to the object which is passed to createEngine
Basically this is intercepting the cache module factory call and adding a compiler options param if there isn't one. The new compiler options contains the ResourceLoader provider which is defined in the first file. The correct solution would either be to supply this resource loader as part of angular-universal or (probably better) allow us to pass in the compiler options as a property so we can do it ourselves.