Skip to content

[@ngtools/webpack] Webpack cannot distinguish on context and would fail to load the proper one. #10128

Closed

Description

@evgeniyefimov

Versions

node: v8.11.0
npm: 5.7.1
Windows 10
"@angular/animations": "5.2.9",
"@angular/cdk": "5.2.4",
"@angular/common": "5.2.9",
"@angular/compiler": "5.2.9",
"@angular/core": "5.2.9",
"@angular/forms": "5.2.9",
"@angular/http": "5.2.9",
"@angular/platform-browser": "5.2.9",
"@angular/platform-browser-dynamic": "5.2.9",
"@angular/router": "5.2.9",
"@angular/compiler-cli": "5.2.9",
"@ngtools/webpack": "1.10.2",
"typescript": "2.7.2",
"webpack": "3.11.0",

Repro steps

app-routing.module.ts

export const ROUTES: Routes = [
    {
        loadChildren: "./student/student.module#StudentModule",
        path: "student",
    },
];

student-routing.module.ts

export const ROUTES: Routes = [
     {
         loadChildren: "./question/question.module#QuestionModule",
         path: "question",
     },
     {
         loadChildren: "./settings/settings.module#SettingsModule",
         path: "settings",
     },
];

question-routing.module.ts

export const ROUTES: Routes = [
     {
         loadChildren: "./settings/settings.module#SettingsModule",
         path: "settings",
     },
];

Observed behavior

ERROR in NaNbut they point to different modules "(C:/Projects/Web/App/src/student/settings/settings.module.ts and "C:/Projects/Web/App/src/student/questions/settings/settings.module.ts"). Webpack cannot distinguish on context and would fail to load the proper one.

Desired behavior

We have a lot of modules with the same names (settings, instructions, etc.), but they are belong to different parents with different urls, they are not exported outside of the parent's scope. It works fine with awesome-typescript-loader, angular-router-loader and angular2-template-loader. We expected the same behavior with @ngtools/webpack.

Mention any other details that might be useful (optional)

I removed all other lazy modules from the project to check and this issue was still there.
Tried to use absolute paths as described here #8722 (comment), but had another issue
ERROR in Could not resolve module App/src/student/student.module relative to C:/Projects/Web/App/src/app-routing.module.ts

tsconfig.json

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom" ],
    "module": "commonjs",
    "moduleResolution": "node",
    "removeComments": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules"
  ]
}

webpack.config

const srcPath = path.resolve(__dirname, "App/src");

module.exports = {
    entry: {
        app: srcPath + "/main.ts",
        polyfills: srcPath + "/polyfills.ts",
        vendor: srcPath + "/vendor.ts",
    },
    resolve: {
        extensions: [".ts", ".js"],
    },
    module: {
        loaders: [
            {
                    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                    loader: "@ngtools/webpack",
            },
        ]
    },
    plugins: [
            new AngularCompilerPlugin({
                tsConfigPath: "./tsconfig.json",
                entryModule: "./App/src/app.module#AppModule",
            }),
            new webpack.optimize.ModuleConcatenationPlugin(),
            new HardSourceWebpackPlugin(),
    ]
};

Activity

  1. tobihagemann commented on Aug 7, 2018

    @tobihagemann

    I also had trouble with this. Didn't understand why absolute paths wouldn't work. The solution is that you have to be aware where your baseUrl is. See this comment on Stack Overflow: https://stackoverflow.com/questions/47601637/angular-4-could-not-resolve-submodule-for-for-routing#comment88223393_48028980

    E.g., if you have "baseUrl": "./" in your root tsconfig.json, your absolute path probably begins with src/app/….

    E.g., if you have "baseUrl": "./" in your src tsconfig.app.json, your absolute path probably begins with app/….

    It all depends on how you set up your project structure and named your directories. In my case, I had to prepend a src/ to my absolute paths.

  2. mgechev commented on Dec 26, 2018

    @mgechev
    Member

    Are you still able to reproduce this issue with the latest version?

  3. socialbi commented on Jan 9, 2019

    @socialbi

    I'm still getting the issue. If I use the absolute path, the issue goes away. I have multiple modules with the same name but different paths. Any suggestions as to how to resolve this error? thanks
    Angular: 7.1.3
    webpack 4.23.1

  4. eggp commented on Jan 9, 2019

    @eggp

    @mgechev
    Hello,
    I also have this problem right now
    I made a sample code: https://github.com/eggp/ng-7-lazy-build-error

    my test build command: ng build --configuration=production
    result:
    selection_127

    master branch ng cli version: 7.1.3
    cli7.2.1 branch is actual cli version

  5. jvoigt commented on Jan 22, 2019

    @jvoigt

    same here

  6. mgechev commented on Jan 22, 2019

    @mgechev
    Member

    We'll look at this during the weekly triage meeting.

  7. removed
    needs: discussionOn the agenda for team meeting to determine next steps
    on Jan 24, 2019
  8. mgechev commented on Jan 24, 2019

    @mgechev
    Member

    Currently this is working as intended. Here's a workaround:

    // student-routing.module.ts
    
    export function _lc() {
      return import("./settings/settings.module").then(m => m.SettingsModule);
    }
    
    export const ROUTES: Routes = [
         {
             loadChildren: "./question/question.module#QuestionModule",
             path: "question",
         },
         {
             loadChildren: _lc,
             path: "settings",
         },
    ];
    // question-routing.module.ts
    
    export function _lc() {
      return import("./settings/settings.module").then(m => m.SettingsModule);
    }
    
    export const ROUTES: Routes = [
         {
             loadChildren: _lc,
             path: "settings",
         },
    ];

    This is bad DX, so I'd suggest to keep the issue open until we figure out how to improve.

  9. self-assigned this
    on Jan 24, 2019
  10. jvoigt commented on Jan 25, 2019

    @jvoigt

    When i use @mgechev s Workaround tsLint will complain:

    [ts] Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'. [1323]

    with my tsconfig.json like this:

    {
      "compileOnSave": false,
      "compilerOptions": {
        "baseUrl": "./",
        "outDir": "./dist/out-tsc",
        "sourceMap": true,
        "declaration": false,
        // "module": "es2015",  // just Changed that
        "module": "esnext",
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es5",
        "typeRoots": [
          "node_modules/@types"
        ],
        "lib": [
          "es2018",
          "dom"
        ]
      }
    }
    

    in JIT it will work regardless but fail in AOT.

    my package.json deps:

    "dependencies": {
        "@angular/common": "^7.2.2",
        "@angular/core": "^7.2.2",
        "@angular/forms": "^7.2.2",
        "@angular/http": "^7.2.2",
        "@angular/platform-browser": "^7.2.2",
        "@angular/platform-browser-dynamic": "^7.2.2",
        "@angular/router": "^7.2.2",
        "@ionic-native/core": "^5.0.0",
        "@ionic-native/splash-screen": "^5.0.0",
        "@ionic-native/status-bar": "^5.0.0",
        "@ionic/angular": "^4.0.0",
        "core-js": "^2.5.4",
        "rxjs": "~6.3.3",
        "zone.js": "~0.8.29"
      },
    
    
  11. mgechev commented on Jan 25, 2019

    @mgechev
    Member

    Yes, won't work with AoT, you're right. The quickest workaround would be to rename one of the routes:

    // question-routing.module.ts
    
    export const ROUTES: Routes = [
         {
             loadChildren: "./settings/settings.module#QuestionSettingsModule",
             path: "settings",
         },
    ];
  12. eggp commented on Jan 27, 2019

    @eggp

    NO, you try full absolute path, working!
    I add new branch to my test code(branch: test-absolute-path), check my diff eggp/ng-7-lazy-build-error@c2405b2
    working lazy build, just change ng styleguide to relative path loadChildren ...
    i would use the relative but i dont know until this problem is up :(

    so it can be used with an absolute route, however the only question is how long it lasts

    ps:
    sorry my english is not the best

  13. mgechev commented on Jan 27, 2019

    @mgechev
    Member

    @eggp yes, absolute paths work as well. The bug is caused by using the same string as the value for loadChildren.

  14. eggp commented on Feb 6, 2019

    @eggp

    thx, so I understand the nature of the error

  15. farajfarook commented on Mar 5, 2019

    @farajfarook

    @mgechev 's work around solution will not work if you are using AOT. refer angular/angular#23878

    Rather another workaround I used in this instance would be to navigate back one directory level to distinguish the the path for loadchildren. This will only work if you have a folder structure that can accommodate this.

    export const ROUTES: Routes = [
         {
             loadChildren: "../<whatever the folder name of parent module>/settings/settings.module#SettingsModule",
             path: "settings",
         },
    ];
    

    I'm too lazy to rename my files for a workaround solution. I believe this issue will be fixed soon.

  16. gabrielKoloral commented on Mar 28, 2019

    @gabrielKoloral

    same issue here :(

  17. pauldraper commented on Apr 12, 2019

    @pauldraper

    Currently this is working as intended.

    This undocumented, surprising behavior is working as intended?

    This is bad DX, so I'd suggest to keep the issue open until we figure out how to improve.

    What is DX?

  18. gurkin33 commented on May 8, 2019

    @gurkin33

    Hello Everyone,

    @farajfarook, thank you for your note, I resolve the issue in that way:

    export const ROUTES: Routes = [
         {
             loadChildren: "../<whatever the folder name of parent module>/<some_prefix_1>settings/settings.module#SettingsModule",
             path: "settings",
         },
    ];
    export const ROUTES: Routes = [
         {
             loadChildren: "../<whatever the folder name of parent module>/<some_prefix_2>settings/settings.module#SettingsModule",
             path: "settings",
         },
    ];
    

    Thank you one more time!

  19. ashikjs commented on Jun 28, 2019

    @ashikjs

    @farajfarook Thanks for save my day :)

  20. clydin commented on May 27, 2020

    @clydin
    Member

    Closing this since the string-based loadChildren has been deprecated.
    Please see https://angular.io/api/router/LoadChildrenCallback

  21. angular-automatic-lock-bot commented on Jun 27, 2020

    @angular-automatic-lock-bot

    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.

  22. locked and limited conversation to collaborators on Jun 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions