Skip to content
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

[RC5]: Minified bundle breaks #10618

Closed
antonybudianto opened this issue Aug 10, 2016 · 122 comments
Closed

[RC5]: Minified bundle breaks #10618

antonybudianto opened this issue Aug 10, 2016 · 122 comments
Assignees

Comments

@antonybudianto
Copy link

antonybudianto commented Aug 10, 2016

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]
@antonybudianto
Copy link
Author

antonybudianto commented Aug 10, 2016

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

@kylecordes
Copy link

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".

@vthinkxie
Copy link
Contributor

+1

1 similar comment
@robertoforlani
Copy link

+1

@robertoforlani
Copy link

@antonybudianto Which order did you change ?

@kylecordes
Copy link

@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.

@cristimusat
Copy link

cristimusat commented Aug 10, 2016

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

@naomiblack
Copy link
Contributor

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

@IgorMinar
Copy link
Contributor

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.

IgorMinar added a commit to IgorMinar/declarations-bug-repro that referenced this issue Aug 10, 2016
@IgorMinar
Copy link
Contributor

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

@IgorMinar
Copy link
Contributor

@cristimusat
Copy link

cristimusat commented Aug 10, 2016

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.

@antonybudianto
Copy link
Author

antonybudianto commented Aug 10, 2016

@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.

@kylecordes
Copy link

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

@sirajc
Copy link

sirajc commented Aug 11, 2016

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

@oocx
Copy link
Contributor

oocx commented Aug 11, 2016

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

@cristimusat
Copy link

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

@oocx
Copy link
Contributor

oocx commented Aug 11, 2016

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.

@gnujeremie
Copy link

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

@ediri
Copy link

ediri commented Aug 11, 2016

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});

@micaelmbagira
Copy link

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

@kylecordes
Copy link

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.

@jrood
Copy link

jrood commented Nov 3, 2016

I'm using angular 2 in an aspnet core app...which means that publishing to aws involves visual studio...which mean that I'm using the visual studio task runner to run webpack...which means I'm locked into "webpack -p" as the command for prod builds...which means UglifyJsPlugin runs with the default settings and I don't have the luxury of passing parameters such as keep_fnames: true.
Is there any other way around this?

@mchamo
Copy link

mchamo commented Nov 3, 2016

@jrood you should be able to configure that setting in your webpack.prod config file.

@jrood
Copy link

jrood commented Nov 3, 2016

@machmo unfortunately, even if I explicitly add "new webpack.optimize.UglifyJsPlugin({ mangle: {keep_fnames: true}})" to the plugin list, it's overridden by the one with no parameters generated by the -p flag.

@jrood
Copy link

jrood commented Nov 4, 2016

It turns out my problem actually was caused by webpack.optimize.OccurrenceOrderPlugin (webpack -h says that -p only does --optimize-minimize, but the online docs confirm that it also does --optimize-occurrence-order);

MRHarrison added a commit to MRHarrison/angular-cli that referenced this issue Nov 17, 2016
-Set keep_fnames: true fixes the issue.

Found the solutions here:
mishoo/UglifyJS#999
angular/angular#10618 (comment)
MRHarrison added a commit to MRHarrison/angular-cli that referenced this issue Nov 17, 2016
-Set keep_fnames: true fixes the issue.

Found the solutions here:
mishoo/UglifyJS#999
angular/angular#10618 (comment)
MRHarrison added a commit to MRHarrison/angular-cli that referenced this issue Nov 25, 2016
-Set keep_fnames: true fixes the issue.

Found the solutions here:
mishoo/UglifyJS#999
angular/angular#10618 (comment)
@trungvose
Copy link
Contributor

trungvose commented Dec 5, 2016

I am getting the same problem even I have already included the following code in the webpack.config as described on angular.io

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

My project using ASP.NET MVC 4 and Angular 2 is using for one of many single page app we are currently having.

The error I am facing now is during the uglify process, the ngModel is becoming ngmodel (lower case)

zone.js:388Unhandled Promise rejection: Template parse errors:
Can't bind to 'ngmodel' since it isn't a known property of 'input'. ("olumn-main-map>

<input type=checkbox [ERROR ->][(ngmodel)]=showTrafficLayer (ngmodelchange)=mapService.setTraffic($event) /> Show Traffic <"): AppComponent@0:313
Can't bind to 'ngif' since it isn't a known property of 'div'. ("$event) /> Show Traffic
<div class=loading-wrapper [ERROR ->]*ngif=dispatchService.isLoading>
<i class="fa fa-spinner fa-spin fa-3x fa-fw"): AppComponent@0:480
Property binding ngif not used by any directive on an embedded template

Original

<input type="checkbox" [(ngModel)]="showTrafficLayer" (ngModelChange)="mapService.setTraffic($event)" />

Uglify

<input type=checkbox [(ngmodel)]=showTrafficLayer (ngmodelchange)=mapService.setTraffic($event) />

Have anyone faced this issue?

@tasos-ale
Copy link
Contributor

tasos-ale commented Jan 12, 2017

@trungk18 I think you have to also configure your html-loader. Try this:

htmlLoader: {
        minimize: false // workaround for ng2
}

This workaround is from the Webpack production configuration in Angular docs.

@Delagen
Copy link
Contributor

Delagen commented Jan 12, 2017

@tasos-ale check for htmlmin or any other loader. Seems it lowercase attributes in html files

@ronzeidman
Copy link

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

This seems to do the trick for me.

@Delagen
Copy link
Contributor

Delagen commented Jan 12, 2017

Seems html-loader preprocess some options caseSensitive: true is needed option
https://github.com/webpack/html-loader/blob/master/index.js#L99

This is because i don't use plugins that process user options, if no such I wrote own )

@miladchamo
Copy link

miladchamo commented Mar 8, 2017

This issue seems to be back for me. Note, I've upgraded to Typescript 2.0.10 and Angular 2.4.0. The web-pack dev build works fine, but, the web-pack prod build results in the error. Again, it seems related to case-sensitivity, so if I have a property called appName in my component, after the prod build, Angular is looking for appname, which does not exist, and hence, results in the error. Any suggestions are appreciated.

Here is my webpack.prod.js.

var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',

output: {
    path: helpers.root('dist'),
    publicPath: '/Applications/MyApp/dist',
    filename: '[name].[hash].js',
    chunkFilename: '[id].[hash].chunk.js'
},

plugins: [
  new webpack.LoaderOptionsPlugin({
      htmlLoader: {
          minimize: false // workaround for ng2
      }
  }),

  new webpack.NoEmitOnErrorsPlugin(),
  new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
      mangle: {
          keep_fnames: true
          //,
          //minimize: true
      }
  }),
  new ExtractTextPlugin('[name].[hash].css'),
  new webpack.DefinePlugin({
      'process.env': {
          'ENV': JSON.stringify(ENV)
      }
  })      
]

});

@Martin-Luft
Copy link

@miladchamo which wbepack version do you use?

@miladchamo
Copy link

@Martin-Wegner I am using the below for webpack. This is based on the angular.io webpack docs

"webpack": "2.2.1",
"webpack-dev-server": "2.4.1",
"webpack-merge": "^3.0.0"

@Martin-Luft
Copy link

I had no problems with this version...

But I must use:

    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),

    new webpack.LoaderOptionsPlugin({
      test: /\.html$/,
      options: {
        htmlLoader: {
          minimize: false // workaround for ng2
        }
      }
    }),

    new webpack.NoEmitOnErrorsPlugin(),

    new webpack.optimize.UglifyJsPlugin({
      // https://github.com/angular/angular/issues/10618
      mangle: {
        keep_fnames: true
      },
      sourceMap: true
    })

@miladchamo
Copy link

@Martin-Wegner that does not seem to work. Same error as mentioned before.

@Martin-Luft
Copy link

@miladchamo do you have a little GitHub project which shows the problem?

@miladchamo
Copy link

@Martin-Wegner I got this to work. I had to update package.json, to make sure I had updated versions for all dev dependencies. In addition, I had to change this dependency to 2.5.41, in order for the client-side build to work, as mentioned in angular/angular.io#3198

  • "@types/jasmine": "^2.5.35",
    
  • "@types/jasmine": "2.5.41",

Thanks for your assistance along the way. That said, I am still concerned as to how minor versions in these dependencies, have such a significant impact, and it appears that the angular.io docs for webpack and angular https://angular.io/docs/ts/latest/guide/webpack.html are not being kept up to date entirely, or aren't being fully tested. This is the second time, I've run into an issue when following them.

@Maseeharazzack
Copy link

My code works perfectly in dev environment when I try npm run build I get the following error:

ERROR in ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./node_modules/extract-text-webpack-plugin/dist/loader.js?
{"omit":0,"remove":true}!./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/app/communication-center/comm-center
.component.scss
Module build failed:
.all-common-grid {
^
Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex"
in D:\dev\Greater_Giving\CommunicationCenter\src\app\communication-center\comm-center.component.scss (line 1, column 1)
@ ./src/app/communication-center/comm-center.component.scss 2:21-317
@ ./src/app/communication-center/comm-center.component.ts
@ ./src/app/communication-center/comm-center.module.ts
@ ./src/app/app-routing.module.ts
@ ./src/app/app.module.ts
@ ./src/app/main.ts

ERROR in ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./node_modules/extract-text-webpack-plugin/dist/loader.js?
{"omit":0,"remove":true}!./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/assets/style.scss
Module build failed:
/* Imported Stylesheet */
^
Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex"
in D:\dev\Greater_Giving\CommunicationCenter\src\assets\style.scss (line 1, column 1)
@ ./src/assets/style.scss 2:21-286

Following is my code

webpack.config.common.js

var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var helpers = require('./helpers');
var webpack = require('webpack');

module.exports = {
entry: {
'app': './src/app/main.ts',
'polyfills': './src/polyfills.ts',
'styles' : './src/assets/style.scss'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /.ts$/,
use: [
{
loader: 'awesome-typescript-loader',
options: {
transpileOnly: true
}
},
{ loader: 'angular2-template-loader' },
{ loader: 'angular-router-loader' }
]
},
{
test: /.html$/,
loaders: ['html-loader']
},
{
test: /.scss$/,
exclude: [ /node_modules/, helpers.root('src', 'style.scss') ],
use: [ 'to-string-loader', 'css-loader', 'sass-loader' ]
},
{
test: /.scss$/ ,
use: ExtractTextPlugin.extract({
use: 'css-loader!sass-loader'
})
},
{
test: /.(png|jpe?g|gif|svg|woff|woff2|otf|ttf|eot|ico)$/,
use: 'file-loader?name=assets/[name].[hash].[ext]'
}
],
exprContextCritical: false
},
plugins: [
new ExtractTextPlugin({ // define where to save the file
filename: 'styles/[name].bundle.css',
allChunks: true,
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CopyWebpackPlugin([
{
from: 'node_modules/froala-editor/css/',
to: 'assets/froala-editor/css/',
},
{
from: 'node_modules/font-awesome/css/font-awesome.min.css',
to: 'assets/font-awesome/css/font-awesome.min.css',
},
{
from: 'node_modules/font-awesome/fonts',
to: 'assets/font-awesome/fonts'
}
]),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
};

webpack.config.prod.js
var path = require('path');
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var commonConfig = require('./webpack.config.common');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, {
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
mangle: {
keep_fnames: true
}
}),
new ExtractTextPlugin('styles.[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
options: {
htmlLoader: {
minimize: false // workaround for ng2
}
}
}),
new UglifyJSPlugin()
]
});

@Maseeharazzack

sbvhev pushed a commit to sbvhev/todo-angular-firebase that referenced this issue May 29, 2018
- set webpack uglifyjs mangle option `keep_fnames: true`
- workaround for angular/angular#10618
- resolves #81
@barrychapman
Copy link

I am getting this same issue in 7.0.2

@cruze300
Copy link

Ok so I was experience same issue when using for example 'import { TooltipModule } from 'ngx-bootstrap/tooltip';' on my app.module. So my issue was that I wasnt including this module in the ts.spec file for the component the error was talking about. After adding it to the ts.spec file as an import, phantom started understanding what the tooltip module is. Hope this helps.

@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 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.