Skip to content

Universal --bundle-dependencies=all works with --aot but fails with --prod #8900

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
naveedahmed1 opened this issue Dec 16, 2017 · 36 comments
Closed
Assignees
Labels
Milestone

Comments

@naveedahmed1
Copy link

Versions

Angular CLI: 1.6.0
Node: 8.9.1
OS: win32 x64
Angular: 5.1.0
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

@angular/cdk: 5.0.1
@angular/cli: 1.6.0
@angular/flex-layout: 2.0.0-beta.11-b01c2d7
@angular/material: 5.0.1
@angular-devkit/build-optimizer: 0.0.35
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.40
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.0
@schematics/angular: 0.1.10
@schematics/schematics: 0.0.10
typescript: 2.4.2
webpack: 3.10.0

Repro steps

When using below command it works perfectly.

ng build -- --app=ssr --output-hashing=media --aot --bundle-dependencies=all

But when we run below command:

ng build -- --app=ssr --output-hashing=media --prod --bundle-dependencies=all

It throws below warnings:

WARNING in ./node_modules/@angular/core/bundles/core.umd.js
6579:23-44 Critical dependency: the request of a dependency is an expression
    at ImportLazyContextDependency.getWarnings (D:\MyProject\ClientApp\node_modules\webpack\lib\dependencies\ContextDependency.js:39:18)
    at Compilation.reportDependencyErrorsAndWarnings (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:703:24)
    at Compilation.finish (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:561:9)
    at applyPluginsParallel.err (D:\MyProject\ClientApp\node_modules\webpack\lib\Compiler.js:502:17)
    at D:\MyProject\ClientApp\node_modules\tapable\lib\Tapable.js:289:11
    at _addModuleChain (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:507:11)
    at processModuleDependencies.err (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:477:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
 @ ./node_modules/@angular/core/bundles/core.umd.js
 @ ./src/main.server.ts
 @ multi ./src/main.server.ts

WARNING in ./node_modules/@angular/core/bundles/core.umd.js
6599:23-110 Critical dependency: the request of a dependency is an expression
    at ImportLazyContextDependency.getWarnings (D:\MyProject\ClientApp\node_modules\webpack\lib\dependencies\ContextDependency.js:39:18)
    at Compilation.reportDependencyErrorsAndWarnings (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:703:24)
    at Compilation.finish (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:561:9)
    at applyPluginsParallel.err (D:\MyProject\ClientApp\node_modules\webpack\lib\Compiler.js:502:17)
    at D:\MyProject\ClientApp\node_modules\tapable\lib\Tapable.js:289:11
    at _addModuleChain (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:507:11)
    at processModuleDependencies.err (D:\MyProject\ClientApp\node_modules\webpack\lib\Compilation.js:477:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
 @ ./node_modules/@angular/core/bundles/core.umd.js
 @ ./src/main.server.ts
 @ multi ./src/main.server.ts

And when we run the app it shows below error in log:

 StaticInjectorError[InjectionToken DocumentToken]: 
  StaticInjectorError[InjectionToken DocumentToken]: 
    Right-hand side of 'instanceof' is not an object
@hansl
Copy link
Contributor

hansl commented Dec 19, 2017

Hi @naveedahmed1

Could you try with --build-optimizer=false? Also, we need a reproduction here. That doesn't look like a new application (or perhaps it is?).

@hansl hansl added command: build needs: more info Reporter must clarify the issue needs: repro steps We cannot reproduce the issue with the information given type: bug/fix labels Dec 19, 2017
@naveedahmed1
Copy link
Author

Thank you so much @hansl

It seems that --build-optimizer=false doesnt make any difference and show same warning.

To reproduce, you can use the universal starter repo https://github.com/angular/universal-starter and run the below command:

ng build --app=1 --output-hashing=media --prod --bundle-dependencies=all

@naveedahmed1
Copy link
Author

Just to add the issue still exists in v 1.6.3

@naveedahmed1
Copy link
Author

Probably its the reason why server bundles aren't working with --bundle-dependencies=all and throwing below error in log:

An unhandled exception has occurred: StaticInjectorError[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
  StaticInjectorError(Platform: core)[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
    Right-hand side of 'instanceof' is not an object
      TypeError: StaticInjectorError[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
  StaticInjectorError(Platform: core)[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
    Right-hand side of 'instanceof' is not an object
    at Re (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2659372)
    at Se (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2659249)
    at dn (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2682010)
    at _l.insertToken (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2702976)
    at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2661904
    at Fe (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2661919)
    at A (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2657217)
    at Object.parse (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2701906)
    at Object.t.createDocument (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:4257849)
    at Object.t.createWindow (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:4257953)
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: StaticInjectorError[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
  StaticInjectorError(Platform: core)[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
    Right-hand side of 'instanceof' is not an object
TypeError: StaticInjectorError[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
  StaticInjectorError(Platform: core)[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
    Right-hand side of 'instanceof' is not an object
    at Re (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2659372)
    at Se (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2659249)
    at dn (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2682010)
    at _l.insertToken (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2702976)
    at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2661904
    at Fe (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2661919)
    at A (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2657217)
    at Object.parse (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:2701906)
    at Object.t.createDocument (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:4257849)
    at Object.t.createWindow (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:4257953)
   at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.<InvokeExportAsync>d__7`1.MoveNext()

@naveedahmed1
Copy link
Author

@Brocco can you please confirm if you were able to reproduce this issue?

@naveedahmed1
Copy link
Author

naveedahmed1 commented Jan 5, 2018

Ok I think the issue is with the uglifyjs plugin. It seems that angular cli is using --compress and --mangle option with this plugin for server bundles and its causing the issue.

To confirm this, I first build bundle using below command:

ng build --app=ssr --output-hashing=media --aot --bundle-dependencies=all

Then I used uglifyjs using below command

uglifyjs main.bundle.js --output output.js

(main.bundle.js is the server bundle generated in 1st command)

the bundle generated after above command worked perfectly.

Then I tried generating a bundle with --compress and --mangle

uglifyjs main.bundle.js --output output.js --compress --mangle

when I used this bundle it threw the error I mentioned in my 2nd last comment.

An unhandled exception has occurred: StaticInjectorError[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
  StaticInjectorError(Platform: core)[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
    Right-hand side of 'instanceof' is not an object
      TypeError: StaticInjectorError[InjectionToken Application Initializer -> InjectionToken DocumentToken]: 
 

@filipesilva filipesilva added freq1: low Only reported by a handful of users who observe it rarely severity5: regression and removed needs: more info Reporter must clarify the issue needs: repro steps We cannot reproduce the issue with the information given labels Feb 1, 2018
@hansl hansl unassigned Brocco Feb 1, 2018
@speige
Copy link

speige commented Feb 22, 2018

+1

@chaker89
Copy link

I am having the same issue :(. Any solution for that ?

@speige
Copy link

speige commented Apr 20, 2018

I believe this is a duplicate of #8616
I posted a workaround on that issue.

For Angular 5, replace

ng build --prod --output-hashing=false --bundle-dependencies=all

with

ng build --build-optimizer --aot --environment prod --output-hashing=false --bundle-dependencies=all

Your bundle size will be larger, but it will work. Assuming you're using this for SSR without having to install node_modules on your server, I think it's a good workaround. The extra bundle size shouldn't be a major issue for server-side code.

I've also posted a workound for Angular 6 in the other issue, but it's too long to copy/paste here.

@chaker89
Copy link

@speige Thanks .
Now i am having another issue
TypeError: Cannot read property 'subscribe' of undefined

I am starting to feel like angular in general is good for just small projects. as soon as you start having many dependencies everything falls apart and the cost of figuring out what the "Update" broke is huge.

My solution was working and then one update broke everything.

@speige
Copy link

speige commented Apr 20, 2018 via email

@chaker89
Copy link

@speige you're probably right. the thing is there's not one specific command. it's just i updated firebase, that led me to update webpack that led me to use yarn instead of npm that led to install uglifyjs-webpack-plugin which led to change the command. I am sure there's an issue with the updates but not sure where.

Btw Thanks for the help :)
error

@speige
Copy link

speige commented Apr 20, 2018 via email

@chaker89
Copy link

@speige Thanks for the info. But i get that error when i downgrade :

  0% compiling(node:22920) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead                                                                            20% building modules 86/100 modules 14 active …Users\chelkho\Desktop\holmepad\src sync..node_modules\webpack\lib\ContextReplacementPlugin.js:106
                        callback(null, dependencies);
                        ^

TypeError: callback is not a function
    at createContextMap (..\node_modules\webpack\lib\ContextReplacementPlugin.js:106:4)
    at ContextReplacementPlugin.newContentCreateContextMap (...\node_modules\webpack\lib\ContextReplacementPlugin.js:19:5)

my webpack is as follow ( v3.11.0 ) :

const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: {
      server: './server.ts',
 },
  resolve: { extensions: ['.js', '.ts'] },
  target: 'node',
  // this makes sure we include node_modules and other 3rd party libraries
  externals: [/(node_modules|main\..*\.js)/],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    rules: [
      { 
          test: /\.ts$/,
          loader: 'ts-loader'
      }
      
    ]
  },
  
  plugins: [
    // Temporary Fix for issue: https://github.com/angular/angular/issues/11580
    // for "WARNING Critical dependency: the request of a dependency is an expression"
    new webpack.ContextReplacementPlugin(

      /angular(\\|\/)core(\\|\/)@angular/,
      path.join(__dirname, 'src'), // location of your src
      {} // a map of your routes

    ),
    new webpack.ContextReplacementPlugin(
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, 'src'),
      {}
    ),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: false,
        mangle: false,
        comments: false
      }
    })
  ]
}

Any idea why ?

@speige
Copy link

speige commented Apr 21, 2018 via email

@deebloo
Copy link
Contributor

deebloo commented May 4, 2018

@chaker89 I am seeing the same error. (the property subscribe of undefined error) any luck?

@naveedahmed1
Copy link
Author

@deebloo No permanent fix yet, a temporary fix could be:

ng build --app=ssr --output-hashing=media --aot --bundle-dependencies=all
Then use uglifyjs using below command

uglifyjs main.bundle.js --output output.js

It wont be a fully optimized bundle, but works.

@chaker89
Copy link

chaker89 commented May 8, 2018

@Deeblo my error was that i changed the local webpack version in the project but i installed long time ago the webpack globally so when i updated the packages the webpack went to the version 4 which is not supported by angular 5

@aharris
Copy link

aharris commented May 15, 2018

@speige

I've also posted a workound for Angular 6 in the other issue, but it's too long to copy/paste here.

Can you link to that workaround?

@speige
Copy link

speige commented May 16, 2018

@aharris #8616 (comment)

Also, if you happen to be using .net for back-end aspnet/JavaScriptServices#1619

@hansl
Copy link
Contributor

hansl commented Sep 27, 2018

This is still reproducible with the latest master, but a few notes:

  1. optimization is both slightly useless in SSR, and detrimental; you want errors to have the most information in your log files on your server.
  2. aot is also useless, since compilation happens at bootstrap and once the app is up and running there's no template compilation done anymore. You won't save much in a production environment, if anything at all.
  3. the bundle-dependencies flag solves a very specific use case that is almost not supported. Some .Net deployment methods would transfer too many files and cause overflows if dependencies were not bundled. In a exclusively express and Node server, there's no advantage to bundling dependencies versus using node_modules.

That being said, we should probably solve this issue. But in the meantime, you don't have to use optimization (ie. dead code elimination and minification), and you don't have to use AOT.

@naveedahmed1
Copy link
Author

naveedahmed1 commented Sep 27, 2018

I agree the optimization would not be suitable if we need more information in our log files on server. But in my observation on Windows IIS server environment, the optimized bundle(my bundle size ~5mb) is less resource intensive than un-optimized bundle(my bundle size ~12mb).

I achieved the optimized bundle using below commands:

ng build --app=ssr --output-hashing=media --aot --bundle-dependencies=all
uglifyjs main.bundle.js --output output.js

But this no longer works in Angular V 7 betas.

With current version of Angular and CLI AOT works without any issue but I doubt if its support is discontinued for server bundles, it definitely will have adverse effect on Windows environment in terms of resource utilization.

bundle-dependencies is absolutely necessary for .net deployments. Without this successful deployment on Windows Server is not possible and is very unreliable. Plus it tends to hit Windows path-length limitations depending on the deployment target.

I think in Uglifyjs config settings if preserve the class names is used it can help in solving this issue.

@hansl
Copy link
Contributor

hansl commented Sep 27, 2018

I doubt if its support is discontinued for server bundles, it definitely will have adverse effect

We're not discontinuing AOT for server bundles, but we're discouraging it.

But this no longer works in Angular V 7 betas.

What error are you getting?

@speige
Copy link

speige commented Sep 27, 2018

@naveedahmed1 Can you provide more specifics on the extra resource utilization? How much MB RAM was used with/without the optimizations? How much faster was server-side rendering in average milliseconds per page?

If the "extra resources" is not very high, it's probably not worth the extra effort.

@speige
Copy link

speige commented Sep 27, 2018

For windows/iis, couldn't an alternative approach be to include package-lock.json with the deployment package & run "npm install" during deployment?

I believe the path-length limitations only effect visual studio during publish if you include node_modules, because it copies everything to a weird long temp directory path. Also, that makes the final deployment very big. However, I think "npm install" on windows doesn't have these issues. It caches everything in between runs so it's pretty fast even if there are updates. I've also never seen "npm install" on windows have path-length issues.

@naveedahmed1
Copy link
Author

@hansl Below was the error, but it seems it was fixed in Angular 7.0.0-beta.6

Parse error at main.js:157164,23
module.exports = class NodeList extends Array {
^
ERROR: Unexpected token: name (NodeList)
at JS_Parse_Error.get (eval at (C:\Users\UserName\AppData\Roaming\npm\node_modules\uglify-js\tools\node.js:20:1), :71:23)
at fatal (C:\Users\UserName\AppData\Roaming\npm\node_modules\uglify-js\bin\uglifyjs:291:53)
at run (C:\Users\UserName\AppData\Roaming\npm\node_modules\uglify-js\bin\uglifyjs:235:9)
at Object. (C:\Users\UserName\AppData\Roaming\npm\node_modules\uglify-js\bin\uglifyjs:160:5)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)

Currently its working again.

So, below in my angular.json I have:

              "optimization": false,
              "outputHashing": "media",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "bundleDependencies": "all",

And after generating bundle I am using uglifyjs and its working

uglifyjs main.js --output output.js

@naveedahmed1
Copy link
Author

@speige I don't have any specific number for ram and cpu. That was my observation in past, my hosting provider at that time provided details of compute cycles which they call a term calculated on bases of resource (ram+cpu) consumption. If I remember correctly it was somewhere between 30-35% increase for unoptimized bundle.

Regarding path length issue, the web apps developed in .net are usually published through visual studio.
"npm install" on local machine runs perfectly, but deployment of node_modules create issue.

Have you tried your approach for .net core website with SSR/universal enabled? If so, I would really like to know the details and have you noticed any difference in performance between using bundle-dependencies=all vs having multiple separate chunks for lazy loaded modules.

There is a related issue on this as well #8616 and I think @SteveSandersonMS from .Net Core team is the appropriate person to comment on the file length issue and other complication when not using bundle-all-dependencies.

@speige
Copy link

speige commented Sep 27, 2018

I agree that the deployment issue is caused by visual studio's publish. That's why I'd suggest not deploying node_modules through visual studio & instead doing npm install on the server. I haven't personally tried it, but it seems plausible that it'd work.

@naveedahmed1
Copy link
Author

I doubt if its supported on Windows IIS web server. May be that would work when you have root access of the server, login using remote desktop and then run npm install on that specific site directory with admin permissions.

@speige
Copy link

speige commented Sep 27, 2018

It could probably also be done remotely through powershell.

@naveedahmed1
Copy link
Author

I am not sure about it, but I think that would still require elevated permissions.

@speige
Copy link

speige commented Sep 27, 2018

True. Elevated permissions would probably be required. I didn't realize this would be an issue, because I wasn't thinking about support for shared web hosts.

I assume the linux+node/express setup also requires running npm install on the server.

Maybe if you're on a shared web host (or don't have elevated permissions) you shouldn't be doing Universal/SSR ?

@naveedahmed1
Copy link
Author

No I am not talking about shared host but for website deployment you shouldn't be requiring elevated permissions a simple access through ftp account should be sufficient.

@speige
Copy link

speige commented Sep 27, 2018

You're logging a bug because you don't want to type your password?

If there's a valid workaround, let's move on & let them work on more important stuff like Angular v7 & ivy.

I'll drop out of this conversation now. Not trying to start a flaming war & I don't have anything else useful to contribute. But, the issue feels unnecessary to me.

@hansl hansl added the needs: discussion On the agenda for team meeting to determine next steps label Jan 10, 2019
@ngbot ngbot bot added this to the Backlog milestone Jan 10, 2019
@filipesilva filipesilva removed the needs: discussion On the agenda for team meeting to determine next steps label Jun 27, 2019
@alan-agius4
Copy link
Collaborator

Thanks for reporting this issue. This issue is now obsolete due to changes in the recent releases. Please update to the most recent Angular CLI version.

If the problem persists after upgrading, please open a new issue, provide a simple repository reproducing the problem, and describe the difference between the expected and current behavior.

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

No branches or pull requests

10 participants