Skip to content
This repository has been archived by the owner on Aug 7, 2021. It is now read-only.

Commit

Permalink
fix(Angular): add hot loader for lazy loaded NgModules (#747)
Browse files Browse the repository at this point in the history
## 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",
                    ]
                },
// ...
```
  • Loading branch information
sis0k0 authored Dec 18, 2018
1 parent 7f67198 commit 6a9db32
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
17 changes: 17 additions & 0 deletions lazy-ngmodule-hot-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const { safeGet } = require("./projectHelpers");

const LAZY_RESOURCE_CONTEXT = "$$_lazy_route_resource";
const HOT_SELF_ACCEPT = "module.hot && module.hot.accept()";

const isLazyLoadedNgModule = resource => {
const issuer = safeGet(resource, "issuer");
const issuerContext = safeGet(issuer, "context");

return issuerContext && issuerContext.endsWith(LAZY_RESOURCE_CONTEXT);
};

module.exports = function (source) {
return isLazyLoadedNgModule(this._module) ?
`${source};${HOT_SELF_ACCEPT}`:
source;
};
3 changes: 2 additions & 1 deletion projectHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,6 @@ module.exports = {
isTypeScript,
writePackageJson,
convertSlashesInPath,
getIndentationCharacter
getIndentationCharacter,
safeGet,
};
24 changes: 23 additions & 1 deletion projectHelpers.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { getIndentationCharacter, writePackageJson } = require("./projectHelpers");
const { getIndentationCharacter, writePackageJson, safeGet } = require("./projectHelpers");
const fs = require("fs");

describe('projectHelpers', () => {
Expand Down Expand Up @@ -57,6 +57,28 @@ describe('projectHelpers', () => {
});
});

describe('safeGet', () => {
it('should return the correct value of existing properties', () => {
const obj = { a: 15 };
expect(safeGet(obj, 'a')).toBe(15);
});

it('should return undefined for unexisting properties', () => {
const obj = { a: 15 };
expect(safeGet(obj, 'random')).toBeUndefined();
});

it('should return undefined when the first argument is undefined', () => {
let obj;
expect(safeGet(obj, 'random')).toBeUndefined();
});

it('should return undefined when the first argument is not an object and does not have inherited property with the queried name', () => {
const num = 15;
expect(safeGet(num, 'random')).toBeUndefined();
});
});

describe('writePackageJson', () => {
const mockFileSystemApi = () => {
const data = {
Expand Down
1 change: 1 addition & 0 deletions templates/webpack.angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ module.exports = env => {
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
use: [
"nativescript-dev-webpack/moduleid-compat-loader",
"nativescript-dev-webpack/lazy-ngmodule-hot-loader",
"@ngtools/webpack",
]
},
Expand Down

0 comments on commit 6a9db32

Please sign in to comment.