2

I'm lazy loading some of my feature modules in an Angular 6 application. Some of those feature modules have dependencies on JS libraries, which no other modules use, and some which are shared between lazy loaded modules.

At the moment, I'm including those libraries in the angular.json configuration in the scripts array, but that means that all those libraries are eager-loaded with the rest of the application, even though they are only used by the lazy loaded module(s).

Is there a way to lazy load JS libraries with the lazy loaded modules? I'd rather not lazy load it within a component (see How to load external scripts dynamically in Angular?) as this would mean copying the import across components within the module, I'm wondering if this can be done across a module.

marksfrancis
  • 1,722
  • 1
  • 13
  • 14
  • Keep in mind that once your application is built, all of your libraries are stored under a `vendor` file. If you want them not to be bundled, remove them from your node modules and include them into your module as a TS file, that's the only way I see it. –  Jul 24 '18 at 12:37
  • That's a good idea, but some of them are 3rd party JS libraries which might be difficult to convert to TS, and to keep them up to date with the original JS library in future – marksfrancis Jul 24 '18 at 12:43
  • I believe every JS code is valid TS code, so you should not have any issue regarding this. And I understand the second point, but now it's not really Angular or Typescript related anymore, it's more of a webpack question, and I can't help you with that, sorry ! –  Jul 24 '18 at 12:44
  • Unfortunately not :/ JS code is not all valid TS code - see here https://stackoverflow.com/a/14413739/5952236 – marksfrancis Jul 24 '18 at 12:48
  • [I am basing my statement on this question](https://stackoverflow.com/questions/20759532/is-any-javascript-code-a-valid-typescript-code), could you explain why it isn't valid code ? –  Jul 24 '18 at 12:49
  • He is talking about linter errors, there's probably a way to ignore those "errors" ! –  Jul 24 '18 at 12:50
  • In Angular, with the development settings for the build, it allows implicit casts like the one used in the answer you linked. When you used a production build however, it uses stricter type checks (such as the error highlighted in the editor linked in the answer you linked - https://www.typescriptlang.org/play/#src=var%20testVar%20%3D%204%3B%0D%0AtestVar%20%3D%20%22asdf%22%3B%0D%0Aalert(testVar)%3B ), which will fail the build – marksfrancis Jul 24 '18 at 12:52
  • @M.Francis Why cant you just load the libraries in lazy module? – dAxx_ Jul 24 '18 at 12:53
  • @dAxx_ I don't know how - that's the question – marksfrancis Jul 24 '18 at 12:54

2 Answers2

4

We are having the same situation, from our test, if the module is lazy-loading, you can simply just only import the external JS file in the lazy-loading module, then this JS library will load when accessing this module, below is our test example which import anychart.js library.


/// <reference path="../../../node_modules/anychart/dist/index.d.ts"/>
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

// third-party js lib
import '../../../node_modules/anychart/dist/js/anychart-base.min.js';

import { OrdersRoutingModule } from './orders-routing.module';
import { OrderListComponent } from './order-list/order-list.component';

@NgModule({
  imports: [CommonModule, OrdersRoutingModule],
  declarations: [OrderListComponent]
})
export class OrdersModule {}

Leon
  • 282
  • 2
  • 10
  • 1
    What happens if 2 module out of 10 or so modules need the same js files ? If I import the file in both modules, will this be loaded 2 times ? Also will this also work with Angular Universal ? – marcg Feb 20 '22 at 00:57
  • Exactly same question ^. Is it smart enough to tree shake? The op question I figured out using the same technique as above but im very fuzzy on what is happening under the hood. – Spencer Gresoro Jun 23 '23 at 00:03
0

Add the following code in app.component.ts file and load your external js libraries in ngOnInit() method.

ngOnInit() {
    this.loadScript('../assets/js/custom.js');
  }

  public loadScript(url: string) {
    const body = <HTMLDivElement> document.body;
    const script = document.createElement('script');
    script.innerHTML = '';
    script.src = url;
    script.async = false;
    script.defer = true;
    body.appendChild(script);
  }
Shirantha Madusanka
  • 1,461
  • 1
  • 11
  • 16