Skip to content

Angular 5 to 6: Internet Explorer, Loading chunk failed (caused by function rest parameters) #11881

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
arlowhite opened this issue Aug 13, 2018 · 15 comments
Labels
area: @angular-devkit/build-angular needs: repro steps We cannot reproduce the issue with the information given
Milestone

Comments

@arlowhite
Copy link

arlowhite commented Aug 13, 2018

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Command (mark with an x)

- [ ] new
- [x] build
- [ ] serve
- [ ] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [ ] run
- [ ] config
- [ ] help
- [ ] version
- [ ] doc

Have not tested serve with IE.

Versions

Node v8.11.3
npm 6.3.0

Angular CLI: 6.1.3
Node: 8.11.3
OS: linux x64
Angular: 6.1.2
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.7.3
@angular-devkit/build-angular      0.7.3
@angular-devkit/build-optimizer    0.7.3
@angular-devkit/build-webpack      0.7.3
@angular-devkit/core               0.7.3
@angular-devkit/schematics         0.7.3
@angular/cdk                       6.4.3
@angular/cli                       6.1.3
@angular/flex-layout               6.0.0-beta.17
@angular/material                  6.4.3
@angular/material-moment-adapter   6.4.3
@ngtools/webpack                   6.1.3
@schematics/angular                0.7.3
@schematics/update                 0.7.3
rxjs                               6.2.2
typescript                         2.9.2
webpack                            4.9.2

TL;DR and Status

After upgrading to Angular 6, this project's build started to include dependencies of plotly.js that use function rest parameters syntax, which is not supported by Internet Explorer 11.

This seems to be caused by a combination of certain plotly.js imports and redundancy in the project's modules where two different modules import PlotlyComponent and other modules import both of those.

Arlo will try to reproduce this module setup in a new cli project Aug 20-24

Repro steps

Our application was working with Internet Explorer 11 previously.
We upgraded from angular/cli 1.7.4 to 6.1.3 and went through the Angular 6 upgrade process.

polyfills

verified polyfills match a new 6.1.3 project. The meant adding this line:
import 'core-js/es6/weak-map';
Commented animations, which we had previously enabled:
// import 'web-animations-js';

build

ng build --prod --deploy-url "/dashboard-dist/x.y.z/"
(x.y.z is our application version, this path is how we serve the dist)

angular.json
error occurs with optimization true or false.

          "configurations": {
            "production": {
              "optimization": false,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": true,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }

The log given by the failure

The app loads in Edge, Chrome, Firefox, Safari.

Using Internet Explorer 11
The app loads partially. AppModule, CoreModule, AppComponent seem to load fine.
These JavaScript files execute fine: runtime, polyfills, scripts, main

After that, a series of chunks with multiple module names are loaded. The 2nd file (accord to network file load order) has an error.
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/band-aid-band-aid-module-ngfactory~demo-demo-module-ngfactory~press-overflow-press-overflow-module-n~a0d51d90.038dae500f4276aa6c84.js

Error Mesages
SCRIPT1010: Expected identifier
Error: Loading chunk MYCHUNK failed.
with optimization=false, this line is

// get all points within the passed range
function (range ( ...args ) {
    let options
    // ...
}

My guess is that Internet Explorer does not support the Array spread operator. Is this the case?
Internet Explorer does not support function Rest Parameters

Here is tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ],
    "noImplicitAny": false,
    "suppressImplicitAnyIndexErrors": false,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "strictNullChecks": false,
    "strictPropertyInitialization": false,
    "downlevelIteration": true,
    "module": "es2015"
  }
}

I tried adding "downlevelIteration": true but it didn't fix the issue.

Here are those chunks (with --named-chunks on). The error is with the second of these (the first is harmony export/imports and does not contain rest parameter syntax). These load in all browsers. What are these chunks?

https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/admin-admin-module-ngfactory~band-aid-band-aid-module-ngfactory~demo-demo-module-ngfactory~press-ove~a1bd9788.5d054c3f7a4445b2ba1e.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/band-aid-band-aid-module-ngfactory~demo-demo-module-ngfactory~press-overflow-press-overflow-module-n~a0d51d90.038dae500f4276aa6c84.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/band-aid-band-aid-module-ngfactory~demo-demo-module-ngfactory~press-overflow-press-overflow-module-n~c989da39.063eb968f9c8f1de7507.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/band-aid-band-aid-module-ngfactory~demo-demo-module-ngfactory~pwp-datasets-datasets-module-ngfactory~c6612e97.d26d4e796e6b47228cb5.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/admin-admin-module-ngfactory~band-aid-band-aid-module-ngfactory~press-overflow-press-overflow-module~dcc0462d.fb22234d681c2ffcf2a0.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/band-aid-band-aid-module-ngfactory~press-overflow-press-overflow-module-ngfactory~pwp-pwp-module-ngf~6538aa28.fc01e498d5c8e5f0e226.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/band-aid-band-aid-module-ngfactory~press-overflow-press-overflow-module-ngfactory~pwp-pwp-module-ngf~e08b67b9.74a917b3f8c6fb8f698e.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/demo-demo-module-ngfactory~pwp-pwp-module-ngfactory.57ec61eee1fce6678b23.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/common.ac5aa9e1fdff127766b5.js
https://MYHOST.com/dashboard-dist/2.6.1-45-g4b99f71/pwp-pwp-module-ngfactory.8c848858c8031a97b6c5.js

band-aid, press-overflow, demo, admin are all are lazy-loaded and I don't expect them to be loading on the homepage. I'm wondering if there's some kind of dependency problem causing them to be loaded early. However, since the app works in other browsers this seems like a separate issue.

Desired functionality

Internet Explorer 11 should work as it did in Angular5 with cli 1.7.4

Troubleshooting Tips

For anyone encountering a similar issue.
The Internet Explorer error is due to unsupported JavaScript syntax. In my case, the build system was pulling in raw dependencies of plotly.js from my node_modules.

  1. Determine what dependency is the issue
    In angular.json set "optimization": false,
  2. rebuild and examine where the error occurs in Internet Explorer. Determine some text to search for that identifies the problematic code.
  3. search for that same text in your node_modules to find the dependency, which was plotly.js in my case (node_modules/plotly.js/dist/plotly.js) and its dependency (node_modules/point-cluster/quad.js)
  4. review your imports and modules related to that dependency, fix any redundancy in your modules and/or clean-up imports
@arlowhite arlowhite changed the title Angular 5 > 6 Internet Explorer Loading chunk failed Angular 5 to 6: Internet Explorer, Loading chunk failed (caused by function rest parameters) Aug 14, 2018
@ngbot ngbot bot added this to the needsTriage milestone Aug 14, 2018
@santialbo-actimo
Copy link

Is there any hack to overcome this issue? Not supporting ie 11 is quite a regression.

@dhknudsen
Copy link

For anyone supporting IE, this is a major issue. Any feedback on the status of this issue would be highly appreciated.

@clydin
Copy link
Member

clydin commented Aug 16, 2018

The code in question appears to originate from a third-party module. Is Plotly.js being used within the project? IE does not fully support ES6 and as a result third-party code that assumes otherwise will fail at runtime.

For an explanation regarding the chunks, please see this comment: #10364 (comment)

@clydin clydin added the needs: more info Reporter must clarify the issue label Aug 16, 2018
@arlowhite
Copy link
Author

arlowhite commented Aug 16, 2018

@clydin yes, we're using Plotly.js "plotly.js": "^1.39.4"
Production is on Plotly.js 1.39.2; I'll verify this wasn't changed in 1.39.4

angular.json

            "scripts": [
              "node_modules/plotly.js/dist/plotly.min.js"
            ]

I'm a bit confused because scripts references the minified file, which I expect would be used regardless of Angular optimized true | false. But maybe with optimized=false the build system looks for a corresponding script file without the .min? Otherwise, maybe imports are triggering inclusion of the package and my scripts config is redundant.

grep "get all points within the passed range" -R *

node_modules/plotly.js/dist/plotly-gl2d.js:	// get all points within the passed range
node_modules/plotly.js/dist/plotly-with-meta.js:	// get all points within the passed range
node_modules/plotly.js/dist/plotly.js:	// get all points within the passed range
node_modules/point-cluster/quad.js:	// get all points within the passed range
node_modules/regl-scatter2d/gh-pages/copyrights.html:	// get all points within the passed range

node_modules/plotly.js/dist/plotly.js

	// get all points within the passed range
	function range () {
		var args = [], len = arguments.length;
		while ( len-- ) args[ len ] = arguments[ len ];

		var options

You can look at dist/plotly.js on GitHub and it isn't using Rest Parameters.

But in my Angular Dist optimized=false

        // get all points within the passed range
        function range ( ...args ) {
                let options

Is it possible that the build system is optimizing the code and converting it to use Rest Parameters???

I think Plotly type imports are causing it to be pulled into the build. For example:
import { Axis, Config, Data, Layout, ScatterData } from 'plotly.js';

@filipesilva
Copy link
Contributor

I'm not aware of anything in our toolchain adding spread operators. What you add to the scripts array should only go into the scripts bundle too, so if you're seeing this in one of your other bundles then maybe you are importing plotly directly?

Best thing I can say is to setup a minimal reproduction and we can try and debug it as well. You can read here why this is needed. A good way to make a minimal repro is to create a new app via ng new repro-app and adding the minimum possible code to show the problem. Then you can push this repository to github and link it here.

@filipesilva filipesilva added needs: repro steps We cannot reproduce the issue with the information given and removed needs: more info Reporter must clarify the issue labels Aug 16, 2018
@clydin
Copy link
Member

clydin commented Aug 16, 2018

It is here though: https://github.com/dy/point-cluster/blob/master/quad.js#L155

It appears that the project is importing and bundling the library and all of its dependencies.

@arlowhite
Copy link
Author

Yes, something is importing plotly.js in a way I don't expect.

I attempted to reproduce with a new project and wasn't able to.
The only way I can load Plotly into Angular common chunk files is with:
import * as Plotly from 'plotly.js/dist/plotly.js';
But I don't do that in my project.

I only import types (from @types/plotly.js) like this:
import { Axis, Config, Data, Layout, ScatterData } from 'plotly.js';
But in a new project, this doesn't load Plotly.

I'll review my project in more detail.
There are some discrepancies such as:
"baseUrl": "src", in tsconfig.json

I'll review my project config in more detail and try to figure out what's loading Plotly this way.

@arlowhite
Copy link
Author

arlowhite commented Aug 17, 2018

In my plotly.component.ts
Changed
import { Layout, Axis, Config, PlotMouseEvent } from 'plotly.js';
to
import { Layout, Config, PlotMouseEvent } from 'plotly.js';
(Axis was an unused import)
Now the build no longer includes plotly.js dependencies such as that range function from point-cluster. My build works in Internet Explorer now! 👍

I've double-checked this twice because it seemed doubtful. But yes, this one little change to the import line makes the difference.
When I ctrl+click Axis in WebStorm, it takes me to the interface defined in @types/plotly.js, but I wonder if it's also defined somewhere else such that the build system decides to load plotly.js dependencies?

My PlotlyComponent was imported in two different modules in a redundant way. I went back before the above change and removed the redundancy. This also fixes the issue.

I think this issue should remain open for now because this seems like a strange way for the build system to behave. I will try to reproduce the problem in new cli project next week.

@filipesilva
Copy link
Contributor

@arlowhite in this case the build system is behaving as it should: it is including the referenced code. We do not police packages that ships ES2015 code (e.g. with rest operators) in their non-ES2015 entry points.

You should bring this packaging issue up with the package is doing this. I suggest looking directly inside of your node_modules files to find the offending code.

@arlowhite
Copy link
Author

I just accidentally introduced this issue in my project again.
@filipesilva I know this is a weird issue, but I hope this thread helps if this is in fact some problem with angular/cli

Angular CLI: 6.2.3
Node: 8.11.3
OS: linux x64
Angular: 6.1.8
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.7.5
@angular-devkit/build-angular      0.7.5
@angular-devkit/build-optimizer    0.7.5
@angular-devkit/build-webpack      0.7.5
@angular-devkit/core               0.7.5
@angular-devkit/schematics         0.8.3
@angular/cdk                       6.4.7
@angular/cdk-experimental          6.4.7
@angular/cli                       6.2.3
@angular/flex-layout               6.0.0-beta.18
@angular/material                  6.4.7
@angular/material-moment-adapter   6.4.7
@ngtools/webpack                   6.1.5
@schematics/angular                0.8.3
@schematics/update                 0.8.3
rxjs                               6.2.2
typescript                         2.9.2
webpack                            4.9.2

What's odd to me, is that using different interface types causes a significant change in the angular/cli build.

In this case, the fix was (from broken to fixed):

Index: src/app/visualization/plotly/plotly.component.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/app/visualization/plotly/plotly.component.ts	(date 1547506923000)
+++ src/app/visualization/plotly/plotly.component.ts	(date 1547683661000)
@@ -83,7 +83,7 @@
    * xaxis and yaxis are set separately.
    * Plotly mutates this object on label change
    */
-  @Input() layout: Partial<PlotlyLayout>;
+  @Input() layout: Partial<Layout>;
 
   @Input() config: Partial<Config> = {};
 
@@ -469,8 +469,8 @@
   }
 
   // TODO execute with ngOnChanges to layout input?
-  createLayout(): Partial<PlotlyLayout> {
-    let layout: Partial<PlotlyLayout> = Object.assign(
+  createLayout(): Partial<Layout> {
+    let layout: Partial<Layout> = Object.assign(
       {
         autosize: true,
       },
  • TypeScript interface type annotation changes causes a change in the build
  • No import lines are changed
  • No changes to node_modules

Both of these types are imported in both the working and broken states. Only the lines in the patch above changed.
Layout comes from
import { Layout, Config, PlotMouseEvent, PlotSelectionEvent } from 'plotly.js';
It is provided by @types/plotly.js

PlotlyLayout is from
import { AddedPlotlyTrace, PlotlyLayout } from 'app/types/plotly';
These are my extensions to the Layout interface because @types/plotly.js is out of date.

export interface PlotlyLayout extends Layout {
  // missing from @types/plotly.js
  barmode: 'stack' | 'group' | 'relative';
  boxmode: 'group' | 'overlay';
  xaxis: Partial<PlotlyAxis> & {
    showdividers?: boolean;
  };
}

Again, these are TypeScript interfaces, not classes preserved at runtime.

In the working state PlotlyLayout is already imported within plotly.component.ts and even used in a few places. But in this state, angular/cli does not pull plotly.js into the build.

  @Output()
  layoutChange: EventEmitter<PlotlyLayout> = new EventEmitter<PlotlyLayout>();

And yet reversing the patch above (using PlotlyLayout on just those few lines) causes the angular/cli build system to pull plotly.js into the NgModule, which causes the Internet Explorer problem mentioned above.

I load plotly.js via scripts and angular/cli doesn't include it in the build except for when this bug occurs.

            "scripts": [
              "node_modules/plotly.js/dist/plotly.min.js"
            ]

In my tsconfig.json I have:

    "paths": {
      "app/*": ["src/app/*"],
      "api-types/*": ["src/api-types/*"]
    },

which I think is non-standard. Maybe this is a contributing cause?

@filipesilva
Copy link
Contributor

@arlowhite does this still happen with the latest CLI versions? If so, can you setup a simple repro that we can investigate?

@arlowhite
Copy link
Author

@filipesilva We'll update our project to Angular 7 in about 2 weeks. I'll try to reproduce it then.

If I can reproduce it with Angular 7, I'll try to understand the cause and build a simple reproduction.

@yherasymchukarchitech
Copy link

I could confirm that we have on Angular 7.2 same situation with chunks. IE can't read the chunk and breaks the app

@deisbel
Copy link

deisbel commented Aug 7, 2019

I'm having the same issue too.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: @angular-devkit/build-angular needs: repro steps We cannot reproduce the issue with the information given
Projects
None yet
Development

No branches or pull requests

8 participants