I am trying to create a module to dynamicly load modules (like the router does). Currently I am able to do so in dev environment, but I couldn't build my project in production. I narrowed down the problem and I found out that the problem is somewhere where I tried to mimic the router's provideRoutes function with adding ANALYZE_FOR_ENTRY_COMPONENTS to my module's providers like this:
providers: [ { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: dynamicModules, multi: true }, { provide: DYNAMIC_MODULE_PATHS, useValue: dynamicModules }, { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader }, ModuleLoaderService ]
But I keep getting this error: Error: Cannot find 'DynamicModule' in '../dynamic/dynamic.module'
And it doesn't matter if I use absolute or relative path.
The strange part is that with ng serve if I re-save the file where I have the providers then it works just fine.
What I could see from the router's source it should work like this, but maybe I'm missing something.
I ignored this for a long time, but now it causes error for me If I try to build for production.
A sample project can be found here: Sample
It will log message into console.
TL;DR;
I am trying to load modules dynamicly without using any functionality from @angular/router
, so I am using ANALYZE_FOR_ENTRY_COMPONENTS
, but I keep getting this runtime error: Cannot find module 'SomeModule' in 'path/to/some.module'
. The error only appears when I first run ng serve
if I re-save the loader part, then it disappears and everything works fine.
Okay, because nobody helped me I get into this problem again and I found the reason and the solution of my problem.
TL;DR: If you want to load modules dynamicly you MUST provide your module paths like this:
And where you want to load, you can just use SystemJsNgModuleLoader (or the abstraction above it NgModuleFactoryLoader) to load the module given by its path.
You can read my concerns and full description below.
The problem is, that you HAVE TO provide the ROUTES injection token from
@angular/router
package for the compiler to be able to find your module paths and can create a map for its path for webpack. Although, I think it is not really a good solution from angular's side. Because like this you HAVE TO provide theloadChildrens
as routes If these modules are not related to any route, then you have to make routes that will not match to anything, but still they will be inside the Routers config, because the compiler and the router uses the sameInjectionToken
. In My case I didn't want to have theseloadChildrens
to be present in my routerConfig at all, that's why I created custom ModuleLoader myself, but you just cannot avoid adding the loadChildrens to the Router as well.You can also see my answer here