'Is there any way to load third party libraries like pdfmake using CDN in Angular 8 application?

I am using pdfmake library in my angular 8 project for client side pdf generation. I have installed the pdfmake library modules and it is working fine. but this third party library increases angular app build size, as shown below.

To reduce this build size I want to use pdfmake library using CDN link and want to load it dynamically.

Let me know is there any way to load third party libraries from CDN in angular app ?

enter image description here



Solution 1:[1]

After referring some articles and answers, I am able to load the pdfmake library from CDN.

We can do this using two ways.

1. Initially Loading : add script tag in the <head> section of index.html. And access the global library object exported in the window object.

For PDFMake I have added below scripts in head section,

<script src='https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.59/pdfmake.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.59/vfs_fonts.js'></script>

and to use it in component declare it on top of component as declare let pdfMake: any ; use this variable to access pdfmake methods: pdfMake.createPdf(docDefinition)

2. Dynamically Loading : If you want to load library on particular action or in particular component, you add script tag dynamically.

Refer this answer for this approach.

I have written article Loading External Libraries from CDN in Angular on both this approach.

Solution 2:[2]

You can use dynamic import the same way as I've specified in the link. Angular is built using Webpack which is quite smart to workout that import() belongs to it.

I would recommend to create a kind of LibraryResolverService with next contents

public readonly myLib$ = defer(() =>
// webpackChunkName is to have your lib called 'lib.js' when loaded
// there are some other options like prefetch (probably won't work here
// due to defer which I use to not to load library when it's not required
  from(import(/* webpackChunkName: "lib" */ 'lib')))

Then you have to subscribe to it and check in console what you get in output.

Generally you will have default which consists of all you need.

However there are some edge cases when lib is obsolete and it results in nothing after import.

Here I can only suggest writing own script loader which will:

  1. Create the script
  2. Assign it src
  3. Append it to the header
  4. Listen for load event (so that you know the script is loaded)
  5. Notify your app that you are ready to go

Why own script loader instead of async/defer. Becase you can load that way any library on fly you decide and you have full control over the load process (you know when it has been loaded and you control when it starts loading).

Solution 3:[3]

Declare your function using async keyword and use dynamic imports.

async downloadPdf() {
    const pdfMake = await import("pdfmake/build/pdfmake.min");
    const pdfFonts = await import("pdfmake/build/vfs_fonts");
    let dd = {
        content: [
            'First paragraph',
            'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
        ]   
    }
    pdfMake.createPdf(dd,undefined,undefined,pdfFonts).download();
}

Also install

npm install --save @types/pdfmake

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ankit Prajapati
Solution 2 Sergey
Solution 3