---
# System prepended metadata

title: Lazy Loading in NativeScript Angular 8.0

---

# Lazy Loading in NativeScript Angular 8.0

Angular 8.0 deprecates the string syntax for configuring lazy loaded routes in favor of the EcmaScript dynamic `import()`. The `import(specifier)` syntactic form returns a `Promise` for the module namespace object. After the `Promise` is resolved, we fetch the exported `NgModule`.

**Before:**
```javascript
const routes: Routes = [{
  path: 'lazy',
  // The following string syntax for loadChildren is deprecated
  loadChildren: './lazy/lazy.module#LazyModule'
}];
```

**After:**
```javascript
const routes: Routes = [{
  path: 'lazy',
  // The new import() syntax
  loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}];
```

## NativeScript Angular Support

You can use the new lazy loading syntax in NativeScript Angular 8.0 as well!

The [dynamic import proposal](https://github.com/tc39/proposal-dynamic-import) is scheduled for **ES2020**. It has also been implemented by [all major browsers](https://caniuse.com/#feat=es6-module-dynamic-import). Since it's quite new, you need to tell TypeScript to use the latest EcmaScript module spec when compiling your code. Open your `tsconfig.tns.json` file and set the `module` property to `esNext`:

**tsconfig.tns.json**
```json
{
    "extends": "./tsconfig",
    "compilerOptions": {
        "module": "esNext",
        "moduleResolution": "node"
    }
}
```

> **Important!** The [NativeScript Playground](https://play.nativescript.org) doesn't support the dynamic imports yet. For now, stick to the old lazy loading syntax when writing your NativeScript Angular applications in the Playground.

## Automatic Route Migration

Migrating all your routes to the new syntax can be quite tedious. But you can tell TSLint to do it for you!

First, make sure you have TSLint in your project:
```
npm install tslint --save-dev
```

After that, install the `angular-lazy-routes-fix` TSLint rule, created by [Craig Spence](https://twitter.com/phenomnominal):
```
npm install @phenomnomnominal/angular-lazy-routes-fix --save-dev
```

Then, add the rule to your TSLint configuration. If you don't have one, just create a new `tslint.json` file:

**tslint.json**
```json
{
  "extends": [
    "@phenomnomnominal/angular-lazy-routes-fix"
  ],
  "rules": {
    "no-lazy-module-paths": [true]
  }
}
```

Finally, run TSLint with the `--fix` flag:

```
npx tslint -p tsconfig.json --fix
```

The linter will find all usages of the old lazy loading syntax and replace them with dynamic imports.

## How does it work?

The NativeScript runtimes don't support the `import()` syntax natively. However, with some help from webpack and Angular, you can use it in your routing configurations. When you build the project with webpack, the following code:

```javascript
const routes: Routes = [{
  path: 'lazy',
  loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}];
```

is roughly converted to:

```javascript
const routes: Routes = [{
  path: 'lazy',
  loadChildren: requireEnsure('./1.js').LazyModule
}];
```

The file `1.js` is the **lazily-loaded bundle** for the `'/lazy'` route. It contains the `NgModule`, called `LazyModule` together with all `Components`, `Directives` and other `NgModules` that it depends on.

> Sidenote: `1.js` don't contain any third-party packages. Instead, all packages from `node_modules` required somewhere in your application end up in a bundle, called `vendor.js`.

The **lazily-loaded bundle** is loaded from the file system by the `requireEnsure` function. This function is inserted by webpack. The `requireEnsure` function has a different definition if you are building for the browser, Node, or NativeScript.

> Sidenote: In NativeScript, the definition of the function is generated from a template that lives in the [`nativescript-target` for webpack](https://github.com/NativeScript/nativescript-dev-webpack/tree/master/nativescript-target). 

For NativeScript,  the implementation of the `requireEnsure` functions simply loads the file with a `require()` call, and then - caches it. So, in the end, you never actually ship a dynamic `import()` in your application - it's all converted to a good old [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1.1) `require()`. The NativeScript runtimes implement the `require()` function by loading the file from the device file system.

## Summary

The key takeaways from the whole module loading story are:

* Angular 8.0 now recommends loading lazy modules with dynamic `import()`.
* NativeScript Angular 8.0 supports the new configuration syntax, although you still can't use it in the NativeScript Playground.
* You can use TSLint to migrate your existing route configurations.
* Dynamic `import()` is not supported natively but webpack replaces it with `require()` during build.
