angular 2 AOT - with Third Party Libraries

1.3k views Asked by At

I am using Highcharts and Kendo Charts in my angular 2 app, When I try to run through AOT compilation, it throws Errors like

Cannot Import Module

or

HomeModule' is not exported by

or

Cannot Determine Module ..

I came to know that I should import .metadata.json file for all the third party files.

How to create them? or where to find them? or If no such file is present for any third party library what to do?

2

There are 2 answers

2
Shane Voisard On

Per @angular issue comment:

All referenced, 3rd party libraries must include the .metadata.json file along side any .d.ts files they produce otherwise they will not work correctly with ngc. The .metadata.json file contains the information we need that was in the original .ts file but was not included in the .d.ts file. If we don't have that information we cannot generate the factories for the library.

The .metadata.json files are produced automatically by ngc. They should be built and delivered by the library vendor and require the .ts files.

If the 3rd party dependency you want to use doesn't ship with metadata.json files, you can try building it with ngc yourself, but doing so may not be simple. ngc may fail with errors when tsc doesn't, perhaps because the code is not statically analyzable.

0
Michael Kang On

Kendo charts and Highcharts are regular JS libraries - not a TypeScript library that's compiled to JavaScript - metadata.json files are not applicable here.

The libraries should work as is (I've run a test and confirmed that it works). I believe the issue that you're having is likely related to your build.

For most JS libraries, you need to either install the Type Definition file (.d.ts) if they are available:

npm install @types/highcharts

If they don't exist (or the version is incorrect) then you can declare the variable as any instead:

declare var Highcharts:any;

Demonstration (the Proof)

If you want to do a simple test to show that it works, download the following reference application:

https://github.com/pixelbits-mk/ng2-starter-app

Create the re-usable module with Highcharts

Step 1

Unzip the reference application to a folder called "features" (that will be the name of the module).

Step 2

Install the Highcharts package.

npm install highcharts --save

Step 3

Name your module features and give it an initial version number: 1.0.0

package.json

name: 'features',
version: '1.0.0'

Step 4

Create the re-usable component that will contain the chart. Let's keep it simple.

chart.component.ts

import { Component, AfterViewInit } from '@angular/core';
declare var Highcharts: any;

@Component({
    moduleId: module.id,
    selector: 'chart',
    templateUrl: 'chart.component.html'
})
export class ChartComponent implements AfterViewInit {

    ngAfterViewInit() {
        var myChart = Highcharts.chart('container', {
            chart: {
                type: 'bar'
            },
            title: {
                text: 'Fruit Consumption'
            },
            xAxis: {
                categories: ['Apples', 'Bananas', 'Oranges']
            },
            yAxis: {
                title: {
                    text: 'Fruit eaten'
                }
            },
            series: [{
                name: 'Jane',
                data: [1, 0, 4]
            }, {
                name: 'John',
                data: [5, 7, 3]
            }]
        });
    }
}

Make sure you render the DIV for the chart container.

chart.component.html

<div id="container" style="width:100%; height:400px;">
    test
</div>

Step 5

Export the ChartComponent from the module.

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule  } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { ChartComponent } from './chart.component';

@NgModule({
    imports: [
        BrowserModule,
        HttpModule        
    ],
    exports: [ChartComponent],
    declarations: [ChartComponent],
    providers: [/* TODO: Providers go here */],
    bootstrap: [AppComponent],
})
export class AppModule { }

Step 6a (optional)

If you want to test out the component at this stage, include the <chart> tag in app.component.html and build it in DEV and PROD (aot) mode.

npm run dev
npm run app

Step 6b

Build and deploy the features module. This creates the UMD, CJS, and AMD modules in the dist folder if you plan to use JIT and a module loader, or builds the necessary JS and .metadata files in the dist\src folder if you plan to use AOT without a module loader.

gulp module

The features module can now be published to npm:

npm publish

Or you can leave it in shared folder where others can access and install it.

Creating the App that will install the Features Module

Step 1

Download the another copy of the reference application into a folder called 'App'. This application will install the features module you created previously.

Step 2

Install the features module from npm

npm install 'features'

Or install the features module from a shared folder

npm install '../features';

Step 3

Import the features module

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule  } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { AppModule as FeatureModule } from 'features';

import { AppComponent } from './app.component';

@NgModule({
    imports: [
        BrowserModule,
        HttpModule,
        FeatureModule      
        ],
    declarations: [AppComponent],
    providers: [/* TODO: Providers go here */],
    bootstrap: [AppComponent],
})
export class AppModule { }

Step 4

Add the chart tag to app.component.html

app.component.html

<chart></chart>

Step 5

Run the app using the AOT build

npm run app

Step 6

Voila!

enter image description here