Angular-cli: change detection behaving differently with cli build

Created on 17 Oct 2016  路  14Comments  路  Source: angular/angular-cli

OS?

Windows 7

Versions.

angular-cli: 1.0.0-beta.17
node: 6.2.1
os: win32 x64

@angular/common: 2.1.0
@angular/compiler: 2.1.0
@angular/core: 2.1.0
@angular/forms: 2.1.0
@angular/http: 2.1.0
@angular/platform-browser: 2.1.0
@angular/platform-browser-dynamic: 2.1.0
@angular/router: 3.1.0
core-js: ^2.4.1
rxjs: 5.0.0-beta.12
ts-helpers: ^1.1.1
zone.js: ^0.6.25

Repro steps.

When running the app from the angular cli build, change detection does not function as expected.

Unfortunately, our app and the situations in which this issue occurs are prohibitively complex to provide a simple way to reproduce the problem. Essentially, the change detector is not fired in all situations where we would expect it to.

Detailed explanation of the issue can be found here http://stackoverflow.com/questions/40047415/angular-2-change-detection-behaves-differently-with-cli-webpack

The log given by the failure.

No error is thrown, change detection simply fails to run when expected.

1 (urgent) bufix

Most helpful comment

Just for easy reference: If I get this correctly, the workaround can be applied to AngularCLI project by:

  1. clearing / commenting the src/polyfills.ts file
    Clearing / commenting the line that says import './polyfills.ts'; from src/main.ts (line 1)
    (Don't clear the actual src/polyfills.ts file, as it's needed for tests)
  2. Then adding the script files to the scripts array in angular-cli.json, like:

"scripts": [ "../node_modules/core-js/client/shim.min.js", "../node_modules/zone.js/dist/zone.js", "../node_modules/reflect-metadata/Reflect.js" ],

All 14 comments

Hm.... can you try something? In the CLI project, remove everything from src/app/polyfills.ts. Add it via CDN to index.html:

    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>
    <script src="https://unpkg.com/[email protected]?main=browser"></script>
    <script src="https://unpkg.com/[email protected]"></script>

Tell me if change detection behaves the same way as the SystemJS version.

Thank you for the reply. I'll give this a try first thing tomorrow morning when I get to the office and let you know if there's any difference.

Ok tried this and it worked as expected! And without needing to resort to timeouts or any other means of explicitly trigger change detection.

Below is what I commented out of polyfills. Same three scripts and installed versions matched.

import 'core-js/client/shim.min'; import 'zone.js/dist/zone'; import 'reflect-metadata/reflect';

So what's different here other than the "main=browser" in the querystring when pulling down zone?

I really appreciate the response and I'm glad to see this working again, but if you have any ideas as to why it wasn't working the other way I'd be interested to hear them.

Thanks again!

Just as an aside, if I import the polyfill scripts in index.html using local versions I already had in node_modules rather than pulling them down from the CDN, it still works.

I also noticed that in the latest version of the docs re: using webpack on angular.io, zone is pulled in with a require rather than an import like so:

import 'core-js/es6'; import 'core-js/es7/reflect'; require('zone.js/dist/zone');

I tried switching back to using the polyfills.ts with this code and change detection was still broken despite the require.

Also, while the angular docs show this pattern of wrapping zone in a require, the latest angular-cli still uses import on zone.js in the polyfills.ts file created by _ng new_.

Wow! I can confirm this issue too. Thanks @doubletriplezero for the investigation and @filipesilva for the solution cause I was resorting to ChangeDetectorRef.detectChanges() but felt hacky somehow.

Just for easy reference: If I get this correctly, the workaround can be applied to AngularCLI project by:

  1. clearing / commenting the src/polyfills.ts file
    Clearing / commenting the line that says import './polyfills.ts'; from src/main.ts (line 1)
    (Don't clear the actual src/polyfills.ts file, as it's needed for tests)
  2. Then adding the script files to the scripts array in angular-cli.json, like:

"scripts": [ "../node_modules/core-js/client/shim.min.js", "../node_modules/zone.js/dist/zone.js", "../node_modules/reflect-metadata/Reflect.js" ],

I can confirm that the modification to the scripts array in angular-cli.json you suggest above does indeed work and change detection behaves normally.

The only thing I would add is that these three scripts should be placed _before_ any others that might also be listed in the scripts array. We already had two scripts in the script array of angular-cli.json (one for our own common js functions and jQuery.js) and if they were in the array before the other three then the change detector issue still occurred.

But it seems to me that adding these to the scripts array in angular-cli.json is definitely preferred as this will do minification, bundling and tree shaking on these files, where linking the scripts inline in index.html will not.

Thanks again for your help in finding this workaround.

I think this issue can be closed as the workaround does solve the problem, but I'm wondering if the default behavior of the cli and its use of polyfills.ts to load zone needs to be addressed.

Well... there was some talk of how having the zone polyfills being loaded through imports, and it's timing, might affect zones somewhat, but it was a theoretical discussion. We hadn't found a real work example where it happened. Apparently now we have.

Let me keep this open still, we'll try to find more solutions to this problem.

/cc @robwormald @Foxandxss @TheLarkInn

@doubletriplezero something to note is that minification and tree shaking does not currently occur for scripts

@clydin ah ok, thanks, that's good to know.

I updated the workaround instructions above https://github.com/angular/angular-cli/issues/2752#issuecomment-254794575 to accommodate a problem you'd face when using ng test.

In theory, you might still get weird issues in tests, because the scripts section in angular-cli.json doesn't seem to be used with the tests, so they include the polyfills using the malfunctioning way (by importing src/polyfills,ts), and do not benefit from the workaround.

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