angular / angular

Deliver web apps with confidence 🚀

Home Page:https://angular.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[RC5]: Minified bundle breaks

antonybudianto opened this issue · comments

I'm submitting a ... (check one with "x")

[x] bug report
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
Minified bundle breaks, but SOLVED temporarily by either:

Error traces:

lib-2cf12bf509.js:7 Unhandled Promise rejection: Template parse errors:
Can't bind to 'brand' since it isn't a known property of 'as-navbar'.
1. If 'as-navbar' is an Angular component and it has 'brand' input, then verify that it is part of this module.
2. If 'as-navbar' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message.
 ("<as-navbar [ERROR ->][brand]="appBrand"></as-navbar>
<div class="container" style="margin-top: 100px;">
    <router-outlet></"): a@0:11 ; Zone: <root> ; Task: Promise.then ; Value:

Expected/desired behavior
The minified bundle should work as in RC4

Reproduction of the problem
https://github.com/OasisDigital/rc5-declaration-order

npm install

// try run in dev, it works well now
npm start

// try run in prod, the bundle created but break
npm run serve-build

// now try changing the mangle option and retry, it works!

What is the expected behavior?
Should work as in RC4

What is the motivation / use case for changing the behavior?

Please tell us about your environment:

  • Angular version: 2.0.0-rc.5
  • Browser: [all | Chrome 52 | Web Browser
  • Language: [all | TypeScript 1.8.10]

Solved: The problem is the order of the components in declarations field, but it's weird it's only happening in bundled-code, I need early feedback on that when in development

Experienced same problem and got up and running with the same solution.

I am not, as of this moment, particularly a fan of this new behavior :-) and I heartily encourage the team to document it in the change log under "breaking changes".

@antonybudianto Which order did you change ?

@robertoforlani Hopefully someone will have time to write a comprehensive explanation soon. In the meantime here is what I can do in a couple of minutes.

In order to obtain a warning free and error-free working "production" build, you need to edit the NgModule app module definition for your program, specifically the declarations array. This array should contain a list of all of the components and directives in your application.

Now for the harder part. You must perform a "topological sort" of this list, or for those who didn't study computer science formally or recently, you need to rearrange the order of this list such that the components are in reverse order of use, with the components used most "deeply" in your component hierarchy, listed first.

For example, consider if you had five components in your program, A B C D E. If for example component A used component B in its template, and component B used component C in its template, and so on, then the dependencies between these components are A->B, B->C, C->D, D->E, E->F. In this case the correct order to list them in the declarations would be declarations: [E, D, C, B, A].

Fortunately, in most applications there is not such a deep dependency graph among all components. In many cases you will make this error go away just by editing that declarations list to (1) list all your components, and (2) list your directives and fine-grained small components the beginning, as a heuristic.

Experienced almost the same problem.

I have 2 directives (A and B) and 1 component (C).
if the order in declarations is [A, B, C], I get the error above for @input in directive B.
if the order in declarations is [B, A, C], I get the error above for @input in directive A.
A and B don't share any dependencies.
C is using both A and B.
This happens only for bundled build.
I am using cli version 1.0.0-beta.10

Thanks all -- this seems like a bug. @IgorMinar is investigating.

I'm having hard time reproducing the problem. Can someone provide a repro?

I tried @antonybudianto's repo but $(npm bin)/gulp serve-build fails on an http 404 from a test, once I comment out the test gulp task, the app builds and runs without any problems.

To clarify: the order of declarations should not matter. If changing the order changes the behavior then that's a bug that we'll fix.

I created https://github.com/IgorMinar/declarations-bug-repro with cli but even that repo doesn’t repro the issue.

could someone clone it and modify it to repro the issue? thanks

I managed to fix my application.
The problem was that the 2 components weren't using moduleId: module.id in the @component declaration.
Once I added moduleId: module.id prod build is ok.

@IgorMinar , sorry yesterday I pushed some commits to the branch, it should work as expected.
Turned out my AppComponent and NavbarComponent are declared on same module (AppModule), then app.html use navbar component, when bundled, it breaks. and I tried to make navbar into a module itself which AppModule imports, and it solved.

If anyone wants to generate an arbitrarily large application to help prove out tools (and reveal issues like this one), I just updated my "angular2-stress-test" for rc.5 and NgModule:

https://www.npmjs.com/package/angular2-stress-test

npm install -g angular2-stress-test
cd directory-with-your-components-in-it
angular2-stress-test 500

I faced similar issue in bundled release for https://sirajc.github.io/angular2-labs/
I had to add NavbarComponent to bootstrap array
bootstrap: [ AppComponent, NavbarComponent ] while deploying, whereas locally during dev I had only
bootstrap: [ AppComponent]
I encountered this issue few days ago while working on master branch, Thought this is the intended behavior

I also have this problem. Changing the declarations order did not fix it for me.

@oocx try putting moduleId:module.id in each component

Fixed it - I had this error in my unit tests, so I had to fix the declarations in my TestBed.configureTestingModule call instead of my app module.

Same problem here, solved it with the mangle option set to false.

commented

Same problem here the fix from @gnujeremie solved it for me to!

return builder.buildStatic('build/src/js/main.js', 'build/app.js', {minify: true, mangle: false});

Same problem, also happening when using Angular 2 with JavaScript ES5 (even with the normal version, not bundled).

I updates the repro repo:

https://github.com/OasisDigital/rc5-declaration-order

to the latest CLI webpack.2, to verify the problem still occurs... as it is not clear to me whether this is really a core problem, or somehow a problem added by webpack or CLI. Yes, problem still occurs.

commented

I have exactly same problem since updating to Angular2 RC.5. In RC4 all was working very well. Not uglified bundle works well. Also uglified bundle but without --mangle works well but it weights slightly more that it would with mangle

There are two workarounds that were also mentioned here:

  1. reorder things in declarations - which really does not always works because some components might use one another in both ways in which case this approach would not help. However because this helps in some cases then I would suspect that uglified package puts definitions according to order in declarations.
  2. uglify without --mangle which producees minified package but slightly bigger than it would be with mangle from what I observed.

I hope it gets solved. In RC.4 all was working fine in my case with same components and same version of uglifyJS.

Angular 2.0.0-rc.5
browsers-all
typescript: 1.8.10
uglifyJS: 2.4.10

I too experience this issue. My temporary solution was to disable minifying. Waiting for rc.6.

Note: I added moduleId: module.id and it made things worse.
The minified javascript isn't loading anything except a useless error 'home.js:260 Uncaught TypeError: e.match is not a function'

Going to try to add moduleId back but use NgModule?

Then try playing with the order of the declarations?

Is there an actual fix or just keep trying until it works for me?

Update:

"SOLUTION": The solution for me was to remove moduleId: module.id and re-arrange the order of the components in the declarations with NgModule.

Now to figure out why it's not working with moduleId: module.id ?

Update II:
Yah, my time is up for they day...webpack -p is really not liking moduleId at all! :( Moreover, it looks like it never has? bleh

Got a reproducable punkr http://plnkr.co/edit/xrFVK1K0OHkKXj1ERYgj?p=preview

Code

import {NgModule, Component, Input} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

var ComponentA = function() {
    @Component({
        selector: 'component-a',
        template: `component-a <component-b [property]="1"></component-b>`
    })
    class Foo {} // <- this class is named Foo
    return Foo;
}();

var ComponentB = function() {
    @Component({
        selector: 'component-b',
        template: 'component-b property: {{ property }}'
    })
    class Foo { // <- And this class is named Foo, rename it to Foo2 and it works
        @Input() property: string;
    }
    return Foo;
}();

@NgModule({
    imports: [
        BrowserModule,
    ],
    declarations: [
        ComponentA,
        ComponentB,
    ],
    bootstrap: [
        ComponentA,
    ],
})
export class TestModule {}

Error:
image

Renaming one of the class Foo to something else solves the error.
I guess something along the pipeline caches by .name. And class names can collide if mangled.

Same here. I'm using Webpack (https://github.com/AngularClass/angular2-webpack-starter) and the solutions proposed here seem very overkill at first glance. No matter how I order my declarations, I end up getting the same error. Also, while I wouldn't call those proposals hacky, they seem far from usable in a business-critical application.

Regardless, with all due respect to the Angular2 team it's beyond me how this could have made it into RC5. Also, rolling out NgModules at this stage IMHO seems like a very controversial move.

commented

@thecritic using a RCx for a business-critical application is borderline... But that's none of my business... ;)

@ediri @thecritic i do agree with @ediri , that's not the kind of changes supposed to appear in a RC.

Same here. Using systemjs and systemjsBuilder.
Temporary solution: I used gulp-uglify to bundle my files at the end of build process. Removed this pipe and it works.
Using SystemJs without systemjsBuilder (for dev: directly mapped to the node_modules folder) it was no problem.

So it looks more for a bundling/minifiying/uglifying problem than implicit ordering to me...but we'll see

A lot of saying that "ordering declarations in correct order solves the problem".
But what about modules?? Just look at this:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component } from '@angular/core';

/** FOO MODULE **/

@Component({ selector: 'foo', template: 'I am foo!' })
export class FooComponent { }

@NgModule({ declarations: [FooComponent], exports: [FooComponent] })
export class FooModule { }

/** BAR MODULE **/

@Component({ selector: 'bar', template: 'I am bar!' })
export class BarComponent { }

@NgModule({ declarations: [BarComponent], exports: [BarComponent] })
export class BarModule { }

/** ROOT MODULE **/

@Component({ selector: 'app-root', template: '<foo></foo> <bar></bar>' })
export class AppComponent { }

@NgModule({
  imports: [
    BrowserModule,
    FooModule, // <--- Switching these
    BarModule, // <--- Switching these
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule { }

In the given example only I am foo! printed.
If I change FooModule with BarModule in imports then only I am bar! shows up..
What the .....? How should I order to print both of them? 😭

Btw I'm using angular-cli.

The solution proposed in #1644 worked for me:

...
mangle: { screw_ie8 : true, keep_fnames: true }, //prod

@ediri Using an RC in production is bad, there's no question about that (we are not doing that btw). The point that I was trying to make is that most people actually don't expect there to be such significant changes at this stage and migrating to the new modules was obviously inevitable. It basically threw everything apart for us (the app is quite large at this point), refactoring takes time and sometimes - like in this case - refactoring almost seems impossible.

Imagine all of this but adding ngUpgrade in the middle :P

We like rock'n'roll! :)

The (temporary) fix by @hansl works btw, I'm delighted!

[Edit] Actually, not quite sure if that works...

I has complete success with @sirajc's approach of including all of your declarations in the bootstrap section as well, as long as the component you actually want to bootstrap is the first in the array.

@NgModule({
    imports: [BrowserModule, FormsModule],
    declarations: [AppComponent, HomeComponent, FooterComponent],
    bootstrap: [AppComponent, HomeComponent, FooterComponent]
})

I had some success playing with the order of the components in the declarations section (getting the parent component rendering), but in my case I had two peer child components in a parent component and with reordering I only got one child component or the other rendering.

Note: this issue is only when minifying and/or mangling/uglifying.

Thanks to @hansl, we got to the bottom of this last night.

The code generation uses Function#name in several places, which is not a problem with Ahead of Time (AOT) compilation, but if we are in the JIT mode and the input is minified code then name collisions occur.

Declarations reordering might make the problem go away, but there still might be hidden surprises with that approach since its not really solving the problem.

The only safe fix right now is to configure uglify with mangle: { screw_ie8 : true, keep_fnames: true} or use AOT template compilation.

We are looking into an actual fix for JIT.

angular/angular-cli#1662

Tying relevant angular-cli workaround for tracking.

update: JIT fix will required bigger changes in the core since it's not really an issue with the core code/design, but with how the classes are transpiled to functions in various tools. We will consider implementing a workaround in the core once more pressing issue are resolved. In the meantime please use keep_fnames option in uglify or use Angular's AOT compilation with ngc.

commented

@IgorMinar Won't there currently be an issue relying on AOT compilation when using ngUpgrade?
ngUpgrade doesn't utilize the aot code even if it exists.

Aside from this issue with ngUpgrade, I suspect this will mostly be a "doesn't matter at all" in the near future. As soon as CLI uses NGC, that will "raise the bar". Once any random person off the Internet can launch a new project in a couple of minutes with CLI and have template pre-compilation running, no one seriously using Angular to to the point they care about production mode, will be able to justify not using NGC. Other tooling will have to catch up very quickly or be abandoned.

Please, do not forgive ngUpgrade users, Angular team promote ngUpgrade as a way to officially jump on the Angular 2 boat without doing a complete rewrite. And I understand to be used in production too.

There's not enough feature complete UI projects (Material design, ng2-bootstrap, ui-bootstrap) to completely use Angular 2 right now. It's the last requirement I have to fully move towards Angular 2. In the meantime I have to deal with ngUpgrade.

It would be fantastic if we can use NGC with ngUpgrade.

If for instance you decide to use ngUpgrade as a step to help migration but to not using it production, please tell us now to taking that into account.

Thanks a lot.

I am facing the same problem and I have been directed to this issue. But I am on Beta 8. Is this issue still applicable in Beta 8?

@Ibrahim-Islam you are on one of the betas affected by a minification issue that lasted like for 10 betas (beta.1 to ~beta.15 or so). It has nothing to do with this issue though.

+1
Using a Webpack build (not CLI) as @IgorMinar suggested building without minifying works... just like the beta releases a several months ago... I am glad I didnt upgrade our app at work last Friday.....

Where do you put mangle: { screw_ie8 : true, keep_fnames: true}? I'm having trouble figuring out how to reconfigure uglify when using angular-cli.

We have already merged this change in master for the CLI.

@TheLarkInn I think @ofuangka was asking: where should this be put today, to have it work, rather than at an unknown future date when a new CLI release ships?

(The best answer is probably: nowhere - instead, use "npm link" to run with the current master CLI instead of the released version.)

@kylecordes Thanks! I was under the impression that the solution could be applied through project configuration. Using npm link worked for me.

Whatchu mean "NGC" @kylecordes ?

"ngc" is the command line Angular 2 template precompiler. It is in the package "npm i @angular/compiler-cli".

@ofuangka just set mangle:false will be ok

Fwiw, it works perfectly in Webpack2 with the mangle options set as described in this thread.

It has been suggested that the solution to this problem is to set mangle=false as follows:

return builder.buildStatic('build/src/js/main.js', 'build/app.js', {minify: true, mangle: false});

I am not seeing where or how to make this change. Can anyone advise?

commented

@nukuuk I have a sample with systemjs builder. I have not confirmed that this fixes it, but you can try it here: https://github.com/thelgevold/angular-2-samples/blob/master/gulpfile.js

commented

It works to set all properties to false, but I have not tried minify = true and mangle = false

@thelgevold I see, you are referring to using systemjs builder with gulp to do bundle/minify etc. Yes I was using this until I recently started using the angular-cli with RC5. I had to set mangle=false to make the builds work. But what is the point of angular-cli with RC5 if we have to fall back on gulp/systemjs builder to bundle?

@nukuuk can you describe exactly what you did? where exactly did you used mangle = false ? I'm using angular cli 1.0.0-beta.10

@cdarken Currently I am using angular-cli 1.0.0-beta.11-webpack.2 with RC5 (the following may not be the case with angular-cli 1.0.0-beta.10, I don't know). And as this thread reports, if you run ng build -prod this will break the app because (presumably)
a) the cli mangles the javascript bundle and angular or webpack doesn't like this, and/or
b) there is some problem with the ordering of the the components in main module declaration.

There is not bug fix for this now, hopefully will happen soon.

In the mean time, my workaround involves running ng build which will bundle the app but not minify/mangle the javascript bundles. Then I am using gulp-uglify with {mangle: false} to concatenate and minify into a final production bundle. It works. But I would much prefer if the angular cli finished the job.

Hmm I've tried to re-order my smaller components etc. as first elements in my declarations, no cigar it now starts complaining about angular-material components which are in a separate module.

I disabled my Uglify plugin for now, I'm using a build based on angularclass webpack starter if anyone cares.

@msegers in the angularclass-webpack-starter you can enable UglifyJsPlugin in the options set

mangle: { screw_ie8 : true, **keep_fnames: true ** }, //prod

@ofuangka this code is a setting for the UglifyJsPlugin in your production webpack.config.js file. It should be placed inside your plugins array.

plugins: [ new UglifyJsPlugin({ mangle: { screw_ie8 : true, keep_fnames: true } }) ]

👍

@mikeeus solution worked fine to me! But I needed to move to https://github.com/mishoo/UglifyJS2 (I was using the first version).

Thanks!

@mikeeus I have the same confusion as @nukuuk with where to put the "mangle" setting - because there is no "webpack.config.js" file (I did a fresh "ng new" with angular-cli 1.0.0-beta.11-webpack.2 - RC5).

So, where do I create the webpack.config.js file and do I need to modify angular-cli.json to use it?

Attached is a screenshot of the files I have with the default angular-cli.json settings.

capture

Guys correct me if I'm wrong but I think that you use the mangle option when you are uglifying the project.

@ricklove, I think that you doesn't Have to use mangle, once your project isn't being minifed / uglified

Solution to fix "ng serve --prod" with "angular-cli 1.0.0-beta.11-webpack.2 - RC5"

Ok, I finally figured out a way by directly changing the file in the node_modules folder, but I imagine there is a better place to do this within my project. Thanks @mikeeus for the setting.

capture2

@herlon214 - It works fine with the normal build, I am trying to do a --prod build which is where I have a problem.

@rickove right now I am not using angular-cli to build for production (ie not using ng build -prod) because, as we have discussed here, it breaks the app. I can't find anyplace where you can set the minifying options ie mangle=false.

For the time being, i am using angular-cli ONLY in development mode (and that has problems too because webpack doesn't seem to be producing good source maps which is causing havoc setting breakpoints). In the event that I need a production build, i am

  1. doing a development build (ng build) then
  2. minifying and concatenating the results with gulp-uglify with the mangle option set to false
    return gulp.src(files) .pipe(concat("main.bundle.min.js")) .pipe(uglify({ mangle: false })) .pipe(gulp.dest("./some/location/js"));

Am looking forward to the next build where this is fixed.

UPDATE: I didn't see @ricklove's solution above editing the webpack config when posting this. His workaround works, ignore this.

@nukuuk, see my last post, it seems to be working for me for the prod build, at least it does reduce the file size to a large degree

There is no fix to keep "keep_fnames" disabled? :( it increased my build file in almost 400kb

This is being worked on by the ng team to fix. This is a workaround so that your builds will still work.

@herlon214 Most likely this is primarily a temporary workaround. I got the impression early in the thread that there is a deeper solution possible that will make it not necessary anymore. Also, apparently it is already not necessary if you use the template precompiler... but doing so is rather tricky at the moment, there is very little out there yet in terms of working examples, support by CLI is on the way but not here, etc.

So for the moment, the obvious thing is to just wave your hands and pretend the extra 400KB is not there, because it is temporary. :-)

@ricklove you are a genius! It works, my production builds are now slim and trim. Many thanks!

Thanks for the explanation @TheLarkInn , @kylecordes 😄

@nukuuk If 1MB counts as slim and trim :) To be fair with gzip it takes mine down to about 250kb, which is actually not bad for a SPA. It sure beats 3MB that's for sure and I can live with these results for now.

Guys, any of you had a problem with gzip ? I'm a bit afraid to use gzip and
some of my clients use a browser that doesn't accept

2016-08-19 12:25 GMT-04:00 Rick Love notifications@github.com:

@nukuuk https://github.com/nukuuk If 1MB counts as slim and trim :) To
be fair with gzip it takes mine down to about 250kb, which is actually not
bad for a SPA. It sure beats 3MB that's for sure and I can live with these
results for now.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#10618 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADQtMWZkEuTQR3dzArWU2oMOKVASRu7Yks5qhdjegaJpZM4JgpvN
.

Att, Herlon Aguiar

commented

Hey Guys.. anyone thats not using gulp minify and is using system js builder try this in your gulp config file.. worked for me:

    builder: {
        normalize: true,
        minify: true,
       // mangle: true, 
        mangle:false,
        runtime: false,
        globalDefs: { DEBUG: false, ENV: 'production' }
    }
};

I am seeing this as well using Webpack and the 'new webpack.optimize.UglifyJsPlugin()' plugin. As @antonybudianto suggested, ordering my module declarations topologically is a valid workaround for now.

Excited to see this one fixed!

I tried rearranging the declarations but that didn't work for me. Adding moduleId: module.id in most of my components however work like magic. kudos to you sir.

Looking forward to the fix.

How does something like this get broken and still released in RC5?

Bundling and minification are not new things, they are an essential and fundamental part of the JavaScript ecosystem. The bundling and minification within Angular 2 has had plenty of issues before - more excusable when it was Alpha or Beta and maybe the first couple of times it happened.

Surely the testing and release system should include some tests that include some bundling and minification?

To @CaptainCodeman 's point, it is concerning that this bug made it this far. I of course understand that regressions are inevitable, especially when working on massive scale projects that are expected to work with any number of unknown plugins and addons from the open source world. Kudos to the Angular team all around.

But that being said, will there be any officially supported compilers, bundlers, and minifiers (etc) like SystemJS and Webpack that will have a large suite of tests and dev effort focused on them? Would anyone on the Angular team be able to add a list of strongly supported, compatible tooling in their documentation? The idea being that if a tool is listed in the docs, it is expected to work, otherwise, use at your own risk (such is open source).

Thanks,
Adam

Hi Guys,

Just to add a small note here, I have disabled the mangle option and the whole UglifyJsPlugin(). But it still breaks the routers.

For example, If I want to navigate to localhost:3000/company and if I have a default redirect like {path: '', redirectTo: '/company', pathMatch:'full'} then this works, but If i try to navigate directly to localhost:3000/company url, then i see a complete blank page( "Get /company" Error (404): "Not found" ). Nor any other route can be loaded (the child routes from /company works, but routes at same level). I will give a try for the AOT solution and post my comment here later.

@ShankarSumanth I think you may need the HashLocationStrategy in your module's provider

i tried the suggestions in the thread. still getting:

Can't bind to 'icon' since it isn't a known property of 'button'. ("ver':hovered,'ui-state-focus':focused,'ui-state-disabled':disabled}" ><button type="button" [ERROR ->][icon]="icon" pButton *ngIf="showIcon" (click)="onButtonClick($event,in)" [ngClass]="): Calendar@7:31 ; Zone: <root> ; Task: Promise.then ; Value: BaseException {message: "Template parse errors:↵Can't bind to 'icon' since …in)" ↵ [ngClass]="): Calendar@7:31", stack: "Error: Template parse errors:↵Can't bind to 'icon'…odules/zone.js/dist/zone.js?1472035648186:365:38)"} Error: Template parse errors: Can't bind to 'icon' since it isn't a known property of 'button'. ("ver':hovered,'ui-state-focus':focused,'ui-state-disabled':disabled}" ><button type="button" [ERROR ->][icon]="icon" pButton *ngIf="showIcon" (click)="onButtonClick($event,in)" [ngClass]="): Calendar@7:31 at new BaseException (http://localhost:5555/node_modules/@angular/compiler/bundles/compiler.umd.js:5116:27) at TemplateParser.parse (http://localhost:5555/node_modules/@angular/compiler/bundles/compiler.umd.js:8318:23) at RuntimeCompiler._compileTemplate (http://localhost:5555/node_modules/@angular/compiler/bundles/compiler.umd.js:15941:55) at eval (http://localhost:5555/node_modules/@angular/compiler/bundles/compiler.umd.js:15869:87) at Set.forEach (native) at compile (http://localhost:5555/node_modules/@angular/compiler/bundles/compiler.umd.js:15869:51) at ZoneDelegate.invoke (http://localhost:5555/node_modules/zone.js/dist/zone.js?1472035648186:332:29) at Zone.run (http://localhost:5555/node_modules/zone.js/dist/zone.js?1472035648186:225:44) at http://localhost:5555/node_modules/zone.js/dist/zone.js?1472035648186:591:58 at ZoneDelegate.invokeTask (http://localhost:5555/node_modules/zone.js/dist/zone.js?1472035648186:365:38)consoleError @ zone.js?1472035648186:484_loop_1 @ zone.js?1472035648186:511drainMicroTaskQueue @ zone.js?1472035648186:515ZoneTask.invoke @ zone.js?1472035648186:437

@ahuvafischer I had the same issue, and only solution worked for me was that I had to list all components in @NgModule in app.module. Whenever I add another modules B and C, then import B and C to my app.module it breaks.

@bahodirk how about third party modules?

@ahuvafischer I am still coping them to dist deployment folder. In index.html:
<script src="../node_modules/moment/min/moment-with-locales.min.js"></script>

With ES5 if declarations are in the "wrong" order some components will simply not be displayed, without any errors. Plunk: plnkr.co/edit/7qi6Um1UzTXBDrV5q1Js

If this is not fixed for 2.0.0 it would be better to say that Angular 2 does not support ES5, period.

I don't think that I'm minifying the bundle, but I've just upgraded a small project to RC5 and am getting the same errors. I updated node_modules/@angular/compiler/src/url_resolver.js like so and it fixes the immediate error for me..

 function _split(uri) {
+    uri += '';
     return uri.match(_splitRe);
 }

The error was that at one point, uri == 114 and wasn't a string. When I added the above code, it fixed it so far.

OK, now that I'm using uglify with mangle: {screw_ie8 : true, keep_fnames: true } set, I'm not sure I need to patch node_modules/@angular/compiler/src/url_resolver.js anymore..

UPDATE:

Nope, I still need it because what's being passed in as the moduleId is still an integer 114 and not a string.
var scheme = url_resolver_1.getUrlScheme(moduleId);

the Function#name minification issue was resolved by 51877ef, once rc.6 is out it should not longer be necessary to tell uglify not to mangle function names.

i am still having the same issue with angular-2.rc6 with webpack2,
when i used mangle: false; in my webpack configuration
the error changed from
t.match is not a function
to
uri.match is not a function
i have opened an issue in angular2-webpack-starter
PatrickJS/PatrickJS-starter#958

@Eslammostafa That's not a minify issue, that's related to this: #10626. Basically, you could either remove any module.id references from the core or third party libraries, or use a string-replace-loader preloader in webpack that strips it, or use the NamedModulesPlugin if you are using the latest version of webpack 2 or manually put .toString() in the part that causes the error in the node_modules folder.

commented

@ricklove Thank you for suggestion, that worked out perfectly for me.

For others:

nano node_modules/angular-cli/addon/ng2/models/webpack-build-production.ts 

edit mangle: { screw_ie8 : true }, //prod to mangle: { screw_ie8 : true, keep_fnames:true }, //prod

ng build -prod

Enjoy!

@ricklove I've upgraded to the latest releases Angular 2.0.0 and Angular CLI 1.0.0-beta.14 but the edit mangle approach is not working.

The webpack-build-production.ts file is in a different location. It now seems to be in;

node_modules/angular-cli/models/webpack-build-production.js

When I edit this file and change it to include keep_fnames:true I still get the error...

`Can't bind to 'customerNumber' since it isn't a known property of 'channel-detail-panel'.

  1. If 'channel-detail-panel' is an Angular component and it has 'customerNumber' input, then verify that it is part of this module.
  2. If 'channel-detail-panel' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message.
    ("nnel-detail-panel *ngFor="let channel of channelList.results"
    [ERROR ->][customerNumber]="customerNumber"
    [channelModel]="channel">
    "): ChannelManagementComponent@10:38`

I've compared the two main.xxxx.bundle.js files with and without this workaround and they are different. The one with the workaround is about 1.47 Mb and one without the change is about 1.32 Mb.

I see this issue has been closed and "included" in release 2.0.1 of Angular but I can't tell what was actually changed.

I've also tried a number of different combinations with the declarations order but I still get the problem.

Which versions of Angular and Angular CLI are people using in which the edit mangle approach works??

Any help would be much appreciated :-)

[Update] - I've just seen @IgorMinar comment about 51877ef fixing this issue in rc.6 but I'm using release 2.0.0 and it still seems to be a problem.

[SOLVED] - Ack, my fault. I think my actual problem was that my selector declaration in the sub-component "channel-detail-panel" wasn't right it was set to "app-channel-detail-panel" when it should have been just "channel-detail-panel" - so the error was right, but not explaining things very well.

I think this issue is working correctly now in Angular 2.0.0 + Angular CLI 1.0.0-beta.14 without the edit mangle workaround. Just make sure your selector declarations are correct.

Seeing same issue. I'm using the webpack intro that is on the angular.io. It works fine when built in dev mode, however, when built in prod mode, the uglify process seems to break it. I tried shuffling the order of declarations in my app module as was suggested above, and now I am seeing errors related to built Angular components (see below), so shuffling order of declarations does not address this.

I am perplexed by these kind of errors, and would hope that the Angular team would be mindful of these kinds of changes, since one can easily waste several hours on these types of errors. Any suggestions are appreciated. Thanks!

Can't bind to 'routerlink' since it isn't a known property of 'a'. ("ab of item.Tabs" style="background-color:#d3d3d3;border:1px solid #fff;padding:5px 5px 5px 5px"> <a [ERROR ->][routerlink]=tab.Link *ngif="tab.IsRoute===true">{{tab.Text}} <a (click)=navigate(tab.Link) *ngif"): AppNav@0:193
Can't bind to 'ngif' since it isn't a known property of 'a'.

@mchamo Isn't your *ngIf spelt wrong? It's not *ngif - it's *ngIf with a capital I.

Hi @rperfect, as I described in my post above, everything works fine when running the app build process in dev mode. Also, my original error message when running in prod build mode was identical to the errors in the beginning of this thread. After shuffling the order of declarations, including shifting AppComponent declaration, as suggested by some of the other posts in this thread, I started seeing the ngIf issue. By going back to my original declaration list, I'm back to original error message. The root cause of the issue seems to be the uglify process with web pack build. Switching back to non-uglified version, i.e, dev build, everything works fine. However, size of page is about 2 MB, hence the desire to minify.

@mchamo you probably have htmlLoader, make sure you set it like so:

      {
        test: /\.html$/,
        loader: 'html',
        options: {
          minimize: true,
          removeAttributeQuotes: false,
          caseSensitive: true, // <- this
          customAttrSurround: [
            [/#/, /(?:)/],
            [/\*/, /(?:)/],
            [/\[?\(?/, /(?:)/]
          ],
          customAttrAssign: [/\)?\]?=/]
        }
      },

@princemaple thanks for the suggestion, still getting the original error message (see below) when running after building for prod mode. Building in dev mode, works fine.

zone.js?fad3:355Unhandled Promise rejection: Template parse errors:
Can't bind to 'appname' since it isn't a known property of 'app-nav'.

  1. If 'app-nav' is an Angular component and it has 'appname' input, then verify that it is part of this module.
  2. If 'app-nav' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message.

@mchamo the only thing you need is:

new webpack.optimize.UglifyJsPlugin({
  mangle: {
    keep_fnames: true
  },
})