Skip to content
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

Relative path of lazy modules calculated from the AppModule instead of the file where the imports are #1347

Closed
AlexAegis opened this issue May 3, 2021 · 3 comments
Labels
bug Something isn't working

Comments

@AlexAegis
Copy link

In the case of the RouterModule.forRoot

Scully tries to resolve the path of lazy modules from the AppModule, where the RouterModule is imported (forRoot) instead of the file where these statements are declared.

If I keep my root route declarations in a separate file, my relative paths to those modules will be different unless that routes.ts files is right next to the app.modules.ts file.

Suppose I keep these lazy modules in a modules folder right next to the app.modules.ts file, then I'd have lazy import like this:

loadChildren: () =>
			import('./modules/foo/foo.module').then((module) => module.FooModule),

If I were to move this config somewhere else, like a config folder next to the app.modules.ts file, so it would be config/routes.ts. In this case these imports would look like this:

loadChildren: () =>
			import('../modules/foo/foo.module').then((module) => module.FooModule),

In this case I have to import from a folder above. This is still a valid project but scully wrongly tries to resolve this from the app.module.ts files perspective instead of the config/routes.ts files perspective.

⠹ Loading guess-parser Error: The relative path "../modules/foo/foo.module" to "<project>/apps/app/src/app/app.module.ts" cannot be resolved to a module
    at Object.exports.getModulePathFromRoute (<project>/node_modules/guess-parser/dist/guess-parser/index.js:334:15)
    at Object.exports.getRoute (<project>/node_modules/guess-parser/dist/guess-parser/index.js:570:34)
    at <project>/node_modules/guess-parser/dist/guess-parser/index.js:938:34
    at visitTopLevelRoutes (<project>/node_modules/guess-parser/dist/guess-parser/index.js:909:13)
    at visitNodes (<project>/node_modules/typescript/lib/typescript.js:27858:30)
    at Object.forEachChild (<project>/node_modules/typescript/lib/typescript.js:28032:24)
    at NodeObject.forEachChild (<project>/node_modules/typescript/lib/typescript.js:146142:23)
    at visitTopLevelRoutes (<project>/node_modules/guess-parser/dist/guess-parser/index.js:912:15)
    at visitNode (<project>/node_modules/typescript/lib/typescript.js:27849:24)
    at Object.forEachChild (<project>/node_modules/typescript/lib/typescript.js:27943:21)

It looks like it always tries to resolve it from the app.module.ts regardless of the importing module. Say I have a routing.module.ts where I do my routing configuration. If I were to place this file in a folder, fix the imports, I would get the same error.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

This also means, that I can have the routing.module.ts in a deeper folder, as long as the routes.ts file is at the same level as app.module.ts.

In the case of the RouterModule.forChild

It looks like the case of forChild is very similar, but the "root" of resolution is the lazy module itself and not the bootstrapped module in the case of forRoot.

So, if I have the import statements of these "second level" lazy modules behind a lazy module, those have to be declared in the same level as the Lazy Module itself, just like in the previous case.

Example error:

⠹ Loading guess-parser Error: The relative path "../modules/bar/bar.module" to "<project>apps/app/src/app/modules/foo/foo.module.ts" cannot be resolved to a module
(rest is the same as in the previous)

And here is the folder structure with the more important files of the previous scenario

├── src
│   ├── app
│   │   ├── modules
│   │   │   └── foo
│   │   │       ├── modules
│   │   │       │   └── bar
│   │   │       │       └── bar.module.ts  <- "second level" lazy module, loaded by foo.module
│   │   │       ├── routing
│   │   │       │   ├── foo-route.module.ts <- Doesn't matter that the routes are imported here or not
│   │   │       │   └── foo.routes.ts <- this is can't be here because of this bug
│   │   │       └── foo.module.ts <- "first level" lazy module
│   │   ├── routes.ts
│   │   ├── app.component.ts
│   │   ├── app.module.ts <- root module
│   ├── assets
│   │   └── scully-routes.json
│   ├── index.html
│   ├── main.ts
│   └── polyfills.ts
└── tsconfig.json

Versions:

	"@angular/core": "11.2.12",
	"@scullyio/ng-lib": "^1.1.1",
	"@scullyio/scully": "^1.1.1",
@AlexAegis AlexAegis added the bug Something isn't working label May 3, 2021
@SanderElias
Copy link
Contributor

@mgechev I took a quick peek, and I think this is the default behavior of GuessParser.
Is this perhaps something I wired up incorrectly?

@mgechev
Copy link

mgechev commented May 3, 2021

@AlexAegis would you open this as a bug in guess-js/guess?

@AlexAegis
Copy link
Author

@mgechev It looks like there is already one describing the same problem: guess-js/guess#345

I'll close this, and mention it there for the more detailed explanation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants