Skip to content
Alexander Vakrilov edited this page Feb 18, 2019 · 6 revisions

⚠️⚠️⚠️ For NativeScript 5.2+ please refer to NativeScript 5.2 HMR with Angular ⚠️⚠️⚠️

Hot Module Replacement

With NativeScript 5.0 there is an option to run your project with Hot Module Replacement enabled. You need to have nativescript-dev-webpack plugin in your project as HMR depends on webpack to work.

Enable HMR in NativeScript Angular Project

In NS angular you will have to add a code that accepts the "hot" changes inside the entry module of your app (usually main.ts). Here is a sample main.ts file you can use:

import { platformNativeScriptDynamic } from "nativescript-angular/platform";
import { AppOptions } from "nativescript-angular/platform-common";

import { AppModule } from "./app/app.module";

let options: AppOptions = {};
if (module['hot']) {
    const hmrUpdate = require("nativescript-dev-webpack/hmr").hmrUpdate;

    options.hmrOptions = {
        moduleTypeFactory: () => AppModule,
        livesyncCallback: (platformReboot) => {
            console.log("HMR: Sync...")
            hmrUpdate();
            setTimeout(platformReboot, 0);
        },
    }
    hmrUpdate();

    // Path to your app module.
	// You might have to change it if your module is in a different place.
    module['hot'].accept(["./app/app.module"]);
}

// !!! Don't forget to pass the options when creating the platform
platformNativeScriptDynamic(options).bootstrapModule(AppModule);

The main thing is that we set up and pass in hmrOptions to the platform bootstrap function. This happens only when HMR is enabled (if (module['hot'])).

Note: You might have to change the following line module['hot'].accept(["./app/app.module"]) to match the path to your AppModule. It should be the same path as the import statement at the start of the file (this one: import { AppModule } from "./app/app.module";).

That's it! You can now use $: tns run [ios/android] --hmr!

Why So Complicated?

But why don't you just automatically insert this code with a webpack loader?

There are a couple of things in the code above, that are dynamic and depend on your project.

  • The path and name of your AppModule
  • The options you pass to the platformNativeScriptDynamic(). You might have custom options.

We might try to insert the code snippet with webpack loader, but it will be error prone as you might have different setup in you main.ts file. It will be very hard to cover all the cases. Given the fact that HMR is still in active development - we decided to play safe and just trust you to set it up yourself.

Limitations

The above code snipper will not work with --aot.

To make it work, you will have to return AppModuleNgFactory instead of AppModule in the moduleTypeFactory function and change the module['hot'].accept(["./app.module"]); to accept the .ngfactory file. What is more annoying - you will have to change the code whenever you run with or without --aot.

For now, we recommend you to stick to hot-module-replacing without AOT.

Bonus

HMR update does trigger the onBeforeLivesync and onAfterLivesync hooks. You can use them to preserve and restore the state of your application. Check out this gist that shows how to preserve the current URL of your app and navigate to it after the HMR. To use it - just import it in your main.ts file: import "./livesync-navigation";.

Clone this wiki locally
You can’t perform that action at this time.