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

HMR does not work for Angular projects, containing lazy loaded modules and the code snippet #1564

Closed
ageorgieva opened this issue Oct 22, 2018 · 4 comments · Fixed by NativeScript/nativescript-dev-webpack#747
Assignees
Labels

Comments

@ageorgieva
Copy link

ageorgieva commented Oct 22, 2018

Environment
CLI: @rc

To Reproduce
Create Master Detail NG app
Add nativescript-dev-webpackа@next
Add nativescript-angular@next
Add the code snippet from: https://github.com/NativeScript/nativescript-angular/wiki/HMR in main.ts file
Deploy on device.

Expected behavior
App should refresh the changes.

Actual behavior
The app is restating and there are info messages in the Console.

Additional context
Related to NativeScript/NativeScript#6398

@ageorgieva ageorgieva changed the title HMR does not work for Angular projects, containing lazy loaded modules (for ex. Master Detail) and the code snippet HMR does not work for Angular projects, containing lazy loaded modules and the code snippet Oct 22, 2018
@sis0k0 sis0k0 self-assigned this Oct 22, 2018
@sis0k0 sis0k0 added the bug label Oct 22, 2018
@etabakov
Copy link
Contributor

Thanks to @vakrilov, we found some manual steps that looks like are valid workaround:

  1. To every lazy loaded NgModule that you want to be hot module replaced add the following snippet:
// imports ...

if (module['hot']) {
    module['hot'].accept();
}

@NgModule({	
    imports: [
  1. Register onBeforeLivesync and onAfterLivesync callbacks to preserve the URL you are app is navigate to as per this Gist:

livesync-navigation.ts

import { Router } from "@angular/router";
import { onBeforeLivesync, onAfterLivesync } from "nativescript-angular/platform-common";
import { RouterExtensions } from "nativescript-angular/router";
import { NgZone } from "@angular/core";
 let cachedUrl: string;
onBeforeLivesync.subscribe(moduleRef => {
    console.log("#### onBeforeLivesync");
    if (moduleRef) {
        const router = <Router>moduleRef.injector.get(Router);
        cachedUrl = router.url;
        console.log("-------> Caching URL: " + cachedUrl);
    }
});
 onAfterLivesync.subscribe(({ moduleRef, error }) => {
    console.log(`#### onAfterLivesync moduleRef: ${moduleRef} error: ${error}`);
    if (moduleRef) {
        const router = <RouterExtensions>moduleRef.injector.get(RouterExtensions);
        const ngZone = <NgZone>moduleRef.injector.get(NgZone);
        if (router && cachedUrl) {
          ngZone.run(() => { // <--  should be wrapped in ngZone
            router.navigateByUrl(cachedUrl, { animated: false });
          });
        }
    }
}); 
  1. Import the livesync-navigation to your main module (main.ts)

@marklanhamhc
Copy link

I've followed all the instructions but now I'm getting a new error:

Module not found: Error: Can't resolve 'css-loader' in '/Applications/MAMP/htdocs/MyApp/app'
 @ ../node_modules/nativescript-dev-webpack/load-application-css-angular.js 5:49-65
 @ ./main.ts```

sis0k0 added a commit to NativeScript/nativescript-dev-webpack that referenced this issue Dec 18, 2018
## What is the current behavior?
In NativeScript Angular the hot updates are only accepted in the entry file (`main.ts`). The lazy loaded NgModules are not directly imported anywhere in the dependency graph with root `main.ts`. That's why the hot updates in lazy modules don't bubble up to the accept in `main.ts` and HMR doesn't work in lazy modules.

## What is the new behavior?
Every lazy loaded NgModule is augmented with HMR self-accept during build by the `lazy-ngmodule-hot-loader`.

fixes NativeScript/nativescript-angular#1564


BREAKING CHANGES:


The `lazy-ngmodule-hot-loader` should be added to the webpack configuration.

**BEFORE**
``` js
// webpack.config.js
                {
                    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                    use: [
                        "nativescript-dev-webpack/moduleid-compat-loader",
                        "@ngtools/webpack",
                    ]
                },
// ...
```

**AFTER**
``` js
// webpack.config.js
                {
                    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                    use: [
                        "nativescript-dev-webpack/moduleid-compat-loader",
                        "nativescript-dev-webpack/lazy-ngmodule-hot-loader",
                        "@ngtools/webpack",
                    ]
                },
// ...
```
@ghost ghost removed the bug label Dec 18, 2018
@sis0k0
Copy link
Contributor

sis0k0 commented Dec 18, 2018

This issue should be fixed with NativeScript/nativescript-dev-webpack@6a9db32.
The fix will be part of the 0.19.0 release of nativescript-dev-webpack.

@nxpatterns
Copy link

Still an issue: HMR does not work if any router resolve involved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants