Issue
I have an angular project structured like so:
Site1
- Module1
- Module2
- SharedModule <- NOT in a library, just a module
Site2
- Module3
- Module4
- SharedModule <- calls module in Main directly
I know this isn't ideal, but it's how it is.
The package.json
files are exactly the same apart from the names of the application.
The project was started on Angular 8 and has always upgraded well, but going from 11 -> 12 I'm having issues:
Site1 builds fine and runs nicely. Site2 builds fine, but errors immediately on running with
Error: inject() must be called from an injection context at injectInjectorOnly (core:4745) at Module.ɵɵinject (core:4755) at Object.RouterModule_Factory [as factory] (router:5999) at R3Injector.hydrate (core.js:11438) at R3Injector.get (core.js:11257) at core.js:11295 at Set.forEach () at R3Injector._resolveInjectorDefTypes (core.js:11295) at new NgModuleRef$1 (core.js:25325) at NgModuleFactory$1.create (core.js:25379)
As Site1 works fine, I assume it must be something in calling that SharedModule?
I've tried adding "preserveSymlinks": true,
to projects.$name.architect.build.options, but that doesn't work. I'm not using npm link
as the other module isn't a library (I know it should have been set up that way, but it isn't).
I've spent at least 2 days trying to get this to work (obviously checking posts such as this and this, but the answers there dont seem to work.
Does anyone know how to fix this, or at least how to debug it please?
Solution
For the benefit of searchers, following not getting a response here, I asked this to Angular themselves.
Here are the answers provided.
You have two distinct workspace trees that import from each other. That is bound to suffer from duplicate @angular/core versions which confuses the runtime, resulting in the rather obscure runtime error you're seeing. You can workaround this using paths mappings, as explained in the library guide here (which also applies to your situation without libs). Not sure why it worked in earlier versions, it has always been prone to these kinds of issues.
and
The cause is that the two separate workspaces both have their own @angular/core packages, and both end up in the bundled application. The Angular runtime keeps its state in top-level module variables that are private to that module, but having two occurrences of that module (from both instances of @angular/core) you run into situations where state is only initialized correctly in one instance, not the other. In this case the injection context is only available in the "primary" runtime, but the parts of the app that were bundled from the "secondary" library parts will depend on the "secondary" runtime state.
So basically, the structure is bad. It should have been done as a proper library project in the first place.
I've made a demo of how it should have been done here.
Answered By - JsAndDotNet
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.