-
Notifications
You must be signed in to change notification settings - Fork 12k
Lazy loading module from library package located in node_modules fails to build. #6373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm having the same issue with version:
Hopefully this can be fixed soon, I'll continue by using --no-aot for the moment. |
@mdewaelebe doesn't the CLI default to JIT? This error happens for me even if I use --aot false. I don't see a --no-aot option. |
@mdewaelebe I think that is a different issue. I get the same error for a lazy route that happens to be local to my project directory or not.
|
I was able to track down the issue. It appears that the AoT plugin discovers lazy routes and passes them to the angular compiler language service to resolve the file name of a given route string. Assuming your library is following the angular package format, this resolves to a definition file, e.g. c:...\node_modules\lib-name\lib-name.d.ts. The file @ngtools\webpack\src\loader.js then uses this path to transpile the source code to es2015 which fails. I modified this file to check for the *.d.ts extension. If there is a match I just use the contents of the pre-compiled .js and .map files for the library. This lets me get past the compilation error in the CLI and when watching the network traffic, I can see the module is loaded on demand. However, this is another hickup, the library is already bundled in the vendor.js file since the webpack configuration simply bundles everything in the node_modules directory into a the vendors file. The only way to get around this, is to eject out of the CLI to exclude the library from the common vendor chunk. All these fixes seem to be a hack, hopefully the cli team can come up with something more elegant. |
…n node_modules fails to build. (angular#6373)
#6755 contains a nice repro of this issue. |
Hello @filipesilva, I have the same issue. Is there any news about a workaround? Thanks,
@angular/cli@1.1.0
|
I've got work around for this which works with uirouter/angular-hybrid (in AOT mode too) but might work with angular router too. So, let's say I've got a library based on angular-quickstart-lib (let's call it quickstart-lib) which has LibModule that I want to lazy load. To do so, I added wrapper around library which lives in Angular CLI based host project. So, in app.module.ts of host, instead of:
I've got: libModuleLazyLoader.ts
and then, in app.module.ts, I've got:
Downside is that you'd need wrapper per library with this work around. hope this helps someone :) |
@adamlubek it works! Thanks! |
Using a different router isn't helpful and I didn't think the CLI supported anything other than the default router. What is the solution to this problem? |
@babeal yes, instead of default Angular router you can use https://github.com/ui-router/angular for pure Angular project or https://github.com/ui-router/angular-hybrid for hybrid AngularJs/Angular project That said, it looks like @Chabane is using default router and got it working. @Chabane , is that correct? |
@adamlubek yes perfect! |
Related to #5986. |
The key to work around from @adamlubek is the 'local' module, QuickstartLibLazyLoader, imports the installed 'LibModule'. This mostly works however it breaks if you try to do a production build.
Turning off AOT will suppress the issue
|
@thekhoi , that's strange as my workaround works for me in production build with AOT. Does your library work with AOT when it's not lazy loaded using my work around? Maybe you have non AOT compliant code somewhere in your library? |
@adamlubek , you're right. It looks like there was an issue with the node package I created for testing. My package name was scoped |
I have the same issue. |
Is it going to be fixed? |
Hi, |
I already posted this in a similar issue (could be a duplicate, but not entirely sure). The loading from webpack is actually working fine, as in it found the correct modules to load via lazy loaded references, but the actual ngfactories for those modules have not been build in the process. You can try my workaround. Basically what you want is to somehow force the compiler to build your factory, but don't have it bundled into the main chunk but into their respective separate chunks. |
I don't think the issue is the same. |
Both workarounds worked for me: |
So why is this not a priority? Lets say we have a bigger business application where all pages are located in a lib. For each customer we create a custom app out of the pages. When you have so many pages Lazy Loading is the way to go because the startup time would be too high otherwise. Now I have to create a wrapper module for 50 pages to make it work correctly?? That is not a reasonable solution at all... |
I'm guessing because the Ivy renderer will fix this issue (and change the way to deal with these things anyway) and they don't want to spend time fixing the "old" behavior. |
Well, that is a valid and reasonable explanation, however, this issue and other related issues are hunting angular community since quite a while now, while having no official statement(apart from Ivy recently). Sure, Ivy will fix that, but why didn't fix happened earlier(without Ivy) given the fact the issue really puts a stain on Angular itself IMHO. |
I know this is a while ago, but how did you manage to solve this? If I change the importAs attributes manually in the generated metadata file for my built libraries indeed it works, but how can I instruct Angular CLI to use the correct (scoped) importAs statement? |
With the recent version of Angular CLI (7.1.4), I might have found another workaround, which is much cleaner. You can find it in angular-demo-lazy-route-libraries repository. Before I had a workaround with wrapper module, that statically imported lazy module and exported it. Then I used that wrapper module to configure But I accidentally discovered that (at least with 7.1.4) I do not need a wrapper module, instead, I can just statically import it in some file, but I do not need to import this file anywhere. By doing this I can keep imports in my routes simple:
Can anyone test the repo as well (more info in README.md)? I tested it on OS X Mojave and Manjaro Linux with latest npm, node and Angular CLI. If that indeed works and I didn't miss something, that means Angular CLI is already close to supporting this feature. The question is if they will go the extra mile. |
@klemenoslaj Nice catch! Much cleaner then wrapping lib modules into app modules. For jit compilation, you can make that work with setting up the path in your tsconfig. I'm used to to this during development to build both app and lib source with webpack, see #10369. While this is generally not recommended, it's quite convenient during development. I have a pipeline running production builds on every commit (using a separate tsconfig), so the risk for libs no being build correctly is mitigated. I was able to test the repo and further enhance it with several (ng-packagr) sub modules. It's even working with the route config in the lib code. |
@tobi-or-not-tobi, great ;) And feel free to make a pull request to my repo adding JIT and other enhancement, so that people could benefit 👍 |
Hi all, This thread was opened a while ago. Having so comments makes it hard for people to find information in anything but the latest comments. But on the other hand I don't think most people would go through all of the comments anyway. New users that see this thread mostly read the first and latest comments and lose things said in between. So for the reasons stated above (high volume of comments, hidden comments, hard to report and inform people) I'm locking this issue to prevent this comment from being lost as new comments come in. Thank you to everyone that reported and helped diagnose the problems and provided workarounds. Our recommended approach to lazy load a library within an angular workspace or node modules, is to use a proxy/wrapper module. With this approach lazy loading will works in both JIT and AOT mode. There are other solutions that work solely in AOT mode such as tsconfig Below find an example of the recommended approach; lazy/lazy.module.ts
app.module.ts
|
Hi all, I am going to close this as following a convo with @alxhub. Lazy loading should happen at an application and not a library level. Hence the above approach is the recommended and the supported way to lazy load a library module in your application. Related to: angular/angular#31893 (comment) |
Bug Report or Feature Request (mark with an
x
)Versions.
Repro steps.
I've modified the quick start library from @filipesilva and copied the output folder to my node_modules/quickstart-lib directory.
Modification includes a routing module to add a child route.
which is then imported into the main LibModule file.
In my host application, I created a simple route to lazy load the module from the library
The log given by the failure.
Desired functionality.
I would like to distribute my code as an NPM library and have the CLI support lazy loading the module that is located in the 'node_modules' directory.
Modules located in the same application directory are lazy loaded just fine.
Mention any other details that might be useful.
The text was updated successfully, but these errors were encountered: