1

I have an app with multiple modules.
One of the modules is to visualize pdf. I use pdf.js which is pretty greedy and the vendor.js is somehow big because of this.

Is there a way to lazyload the library at the same time I lazy load the pdf-module ?

I've noticed this answer, but it doesn't feel as right. Load external js script dynamically in Angular 2

I am not trying to lazyload a module but an external library.

Stefdelec
  • 2,711
  • 3
  • 33
  • 40

2 Answers2

3

If you want to lazy load external libraries such as jquery, jspdf you can create some service like:

lazy-loading-library.service.ts

import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ReplaySubject } from 'rxjs/ReplaySubject';

import { DOCUMENT } from '@angular/platform-browser';

@Injectable()
export class LazyLoadingLibraryService {
  private loadedLibraries: { [url: string]: ReplaySubject<any> } = {};

  constructor(@Inject(DOCUMENT) private readonly document: any) { }

  public loadJs(url: string): Observable<any> {
    if (this.loadedLibraries[url]) {
      return this.loadedLibraries[url].asObservable();
    }

    this.loadedLibraries[url] = new ReplaySubject();

    const script = this.document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    script.onload = () => {
      this.loadedLibraries[url].next('');
      this.loadedLibraries[url].complete();
    };

    this.document.body.appendChild(script);
    return this.loadedLibraries[url].asObservable();
  }
}

And whenever you need some external library just use this service that will load library only once:

app.component.ts

export class AppComponent {
  constructor(private service: LazyLoadingLibraryService) {}

  loadJQuery() {
    this.service.loadJs('https://code.jquery.com/jquery-3.2.1.min.js').subscribe(() => {
        console.log(`jQuery version ${jQuery.fn.jquery} has been loaded`);
    });
  }

  loadJsPdf() {
     this.service.loadJs('https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js').subscribe(() => {
      console.log(`JsPdf library has been loaded`);
    });
  }

Plunker Example

If you're looking for lazy loading angular module then these questions might be helpful for you:

yurzui
  • 205,937
  • 32
  • 433
  • 399
2

I hope you're using Angular CLI.

  1. Install pdfjs-dist package:

    npm install pdfjs-dist

  2. Install types for it:

    npm install @types/pdfjs-dist --save-dev

  3. Add the following import statement to your lazy loaded module file:

    import 'pdfjs-dist';

The last step will embed pdf.js source code in the lazy loaded bundle when you run ng build.

You should be able to access the global PDFJS variable from your code.

Hope this helps.

Community
  • 1
  • 1
Eugene
  • 1,633
  • 12
  • 7