Angular-cli: AOT compiler changing the order of imports

Created on 24 Jan 2018  Â·  6Comments  Â·  Source: angular/angular-cli

Versions

    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / â–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/

Angular CLI: 1.6.5
Node: 6.9.5
OS: win32 x64
Angular: 5.2.1
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cdk: 5.1.0
@angular/cli: 1.6.5
@angular/flex-layout: 2.0.0-beta.12
@angular/material: 5.1.0
@angular-devkit/build-optimizer: 0.0.41
@angular-devkit/core: 0.0.28
@angular-devkit/schematics: 0.0.51
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.5
@schematics/angular: 0.1.16
typescript: 2.4.2
webpack: 3.10.0

Repro steps

  • Installs ng2-charts module and chart.js library:

npm install ng2-charts --save
npm install chart.js --save

  • Installs chart.piecelabel.js plugin for chart.js:

npm install chart.piecelabel.js --save

  • Imports both libraries in app.modules.ts:
import {ChartsModule} from 'ng2-charts';
// ...
import 'chart.piecelabel.js';

chart.piecelabel.js is a chartjs plugin which overlays the labels on pie/donut charts.

  • Develop with ng serve and see everything works as expected.
  • Deploy with ng build --prod and see chart.piecelabel.js plugin not working anymore.

Observed behavior

As this is my first Angular project, my apology if it doesn't qualify an issue report.

My investigation is that the behavior difference (working in dev but not in prod) is caused by a different default compilation strategy: --aot is default to be on when building for production (ng build --prod). When I tried developing with AOT on (ng serve --aot), the same problem is observed.

Note that there is no compilation error. For the prod (AOT) build, chart.piecelabel.js complains not being able to locate the Chart object to inject new behaviors in the console log. But the chart is working properly, just that no label overlay is shown. I think the best guess is that both chart.piecelabel.js and chartjs are loaded, but the loading order is incorrect - the AOT compiler did some tricks causing chart.piecelabel.js being loaded before the Chartjs plugin, and thus the problem.

So it sounds like an import order issue. For now I am inclined to think this is not an expected behavior, so I am reporting here. Again, sorry if this is a false alarm. Any advise or guidance would be greatly appreciated. Thank you!

devkibuild-angular high inconvenient triage #1 bufix

Most helpful comment

For what it's worth, I was able to work around the issue by manually importing the chart.js library and console.log it before importing the chart.piecelabel.js plugin, as suggested by @filipesilva in https://github.com/angular/angular-cli/issues/9058#issuecomment-355021360.

import {ChartsModule} from 'ng2-charts';
import * as Chart from 'chart.js'; // NEW
console.log(Chart); // NEW
import 'chart.piecelabel.js';

All 6 comments

Heya, thanks for the report and reproduction. I think it might be related to https://github.com/angular/angular-cli/issues/9058 but would need to investigate a bit better.

The actual cause of the problem is not that the imports in the file are being reordered but rather that the ChartsModule import no longer exists. In AOT mode, the NgModule within app.module.ts that uses ChartsModule is compiled via the AOT compiler resulting in the import no longer being used within the file. Unfortunately for this situation, this is working as intended. Theoretically, the ng2-charts library could provide a mechanism to register chartjs plugins as it has assumed ownership of the lifecycle of the underlying chartjs library.

For what it's worth, I was able to work around the issue by manually importing the chart.js library and console.log it before importing the chart.piecelabel.js plugin, as suggested by @filipesilva in https://github.com/angular/angular-cli/issues/9058#issuecomment-355021360.

import {ChartsModule} from 'ng2-charts';
import * as Chart from 'chart.js'; // NEW
console.log(Chart); // NEW
import 'chart.piecelabel.js';

@tamcy you may be able to simplify that to:

import {ChartsModule} from 'ng2-charts';
import 'chart.js'; // NEW
import 'chart.piecelabel.js';

Closing as this is working as intended when using AOT mode. The ng2-charts library is also marked as not having side effects. If relying on side effects of the underlying chart.js package than importing it as indicated above would be the correct course of action.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rwillmer picture rwillmer  Â·  3Comments

MateenKadwaikar picture MateenKadwaikar  Â·  3Comments

gotschmarcel picture gotschmarcel  Â·  3Comments

rajjejosefsson picture rajjejosefsson  Â·  3Comments

jbeckton picture jbeckton  Â·  3Comments