Repository navigation
No apparent way to use --bundle-dependencies=all successfully since 1.5.0 #8616
Description
Prior to the 1.5.0 release, it was possible to pass --bundle-dependencies=all --prod to get an AoT compiled self-contained bundle that worked for server-side rendering (SSR) under Node.js. Since 1.5.0, these flags produce a bundle that, as far as I can tell, can never work because they now rely on the existence of browser DOM APIs that don't exist in Node.
If there is any way to use --bundle-dependencies=all successfully in --prod build with 1.5.0+, I'd love to know about it.
Versions
Angular CLI: 1.5.4
Node: 6.11.0
OS: win32 x64
Angular: 5.0.2
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
@angular/cli: 1.5.4
@angular-devkit/build-optimizer: 0.0.33
@angular-devkit/core: 0.0.21
@angular-devkit/schematics: 0.0.37
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.4
@schematics/angular: 0.1.7
typescript: 2.4.2
webpack: 3.8.1
Repro steps
- Clone the example repo at https://github.com/SteveSandersonMS/angular-bundledependencies-repro. This is the same as the universal-starter repo, except for one commit that gets as close as I can to a scenario where
--bundle-dependencies=allcould work (but still doesn't). - Run
npm install - Observe that it works fine in a non-prod build by running
npm run build:ssrthennpm run serve:ssr. If you visit http://localhost:4000, you'll get both server and client rendering. - Observe that if you build in prod mode (run
npm run build:ssr:prodthennpm run serve:ssr), then it does not work - you'll get this error:
TypeError: StaticInjectorError[InjectionToken DocumentToken]:
StaticInjectorError[InjectionToken DocumentToken]:
Right-hand side of 'instanceof' is not an object
at ke (C:\path\angular-bundledependencies-repro\dist\server.js:4106:724114)
at xe (C:\path\angular-bundledependencies-repro\dist\server.js:4106:723991)
at lr (C:\path\angular-bundledependencies-repro\dist\server.js:4106:746752)
at _n.insertToken (C:\path\angular-bundledependencies-repro\dist\server.js:4106:767718)
at C:\path\angular-bundledependencies-repro\dist\server.js:4106:726646
at Fe (C:\path\angular-bundledependencies-repro\dist\server.js:4106:726661)
at I (C:\path\angular-bundledependencies-repro\dist\server.js:4106:721959)
at Object.parse (C:\path\angular-bundledependencies-repro\dist\server.js:4106:766648)
at Object.t.createDocument (C:\path\angular-bundledependencies-repro\dist\server.js:4106:1194422)
at Object.t.createWindow (C:\path\angular-bundledependencies-repro\dist\server.js:4106:1194526)
If you trace this into the server.js bundle code, what's happening is that it's testing whether someValue instanceof HTMLElement (though it's not obvious at first glance because everything is minified and renamed). That code would be OK in a browser, but it's an error in Node, because HTMLElement is undefined. So the generated bundle isn't going to work for SSR under Node.
- If you want, verify that removing
--bundle-dependencies=allfrom lines 22 and 23 inpackage.jsonis enough to make it work in both dev and prod builds. So the problem is the combination of--prodwith--bundle-dependencies=all- you can use either on their own, but not both together.
Observed behavior
Fails with the Right-hand side of 'instanceof' is not an object error shown above.
Desired behavior
SSR works as it did in the non-prod build.
Mention any other details that might be useful (optional)
The equivalent did work pre-1.5.0 (which was also Angular 4.x).
The reason I'm asking about this is because I'm building new Angular CLI-based ASP.NET templates that will be included in the .NET Core SDK and Visual Studio. We want the template to use --bundle-dependencies=all by default because then developers don't have to publish their node_modules to production, and attempting to publish 20,000+ files from node_modules is extremely time-consuming (and not always reliable) from VS. Plus it tends to hit Windows path-length limitations depending on the deployment target.
Activity
naveedahmed1 commentedon Nov 23, 2017
@filipesilva any thoughts on this?
filipesilva commentedon Nov 24, 2017
@Brocco can you take a look please?
naveedahmed1 commentedon Dec 8, 2017
@Brocco did you get a chance to look into this?
asadsahi commentedon Dec 8, 2017
Really love to have this nailed down. Thanks guys.
naveedahmed1 commentedon Dec 28, 2017
@hansl is it due to the issue reported here #8900 ?
naveedahmed1 commentedon Jan 5, 2018
Ok I think the issue is with the uglifyjs plugin. It seems that angular cli is using
--mangleand--compressoption 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=allThen I used
uglifyjsusing below commanduglifyjs 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 --manglewhen I used this bundle it threw the error @SteveSandersonMS mentioned above.
naveedahmed1 commentedon Jan 18, 2018
@filipesilva can you please share if there is any update on this?
naveedahmed1 commentedon Feb 9, 2018
@hansl should we expect this and #8900 to be solved in V6?
If this could be fixed, it would really help developers using Angular and SSR with Windows technologies (.net core) or hosting Angular apps on Windows servers/IIS/Kestrel.
asadsahi commentedon Feb 10, 2018
Personally I would love to have this feature available as soon as possible, but for now I have stopped wasting time and effort on making angular apps universal.
Right now the stability of angular universal is good for demo purposes but as soon as you start expanding application to a good scale you start realising the amount of energy required to maintain those features is quite large. I hope in coming days DX will improve to implement SSR in angular apps and it will be easier like angular cli has done good job developing/building angular apps.
39 remaining items
stefankip commentedon May 21, 2019
I've tried every suggestion in this thread, but still run into this issue:
Error: No NgModule metadata found for '[object Object]'. at NgModuleResolver.resolve (C:\project\node_modules\@angular\compiler\bundles\compiler.umd.js:20020:27) at CompileMetadataResolver.getNgModuleMetadata (C:\project\node_modules\@angular\compiler\bundles\compiler.umd.js:18662:47) at JitCompiler._loadModules (C:\project\node_modules\@angular\compiler\bundles\compiler.umd.js:26085:55) at JitCompiler._compileModuleAndComponents (C:\project\node_modules\@angular\compiler\bundles\compiler.umd.js:26066:40) at JitCompiler.compileModuleAsync (C:\project\node_modules\@angular\compiler\bundles\compiler.umd.js:26026:41) at CompilerImpl.compileModuleAsync (C:\project\node_modules\@angular\platform-browser-dynamic\bundles\platform-browser-dynamic.umd.js:202:35) at C:\project\node_modules\@nguniversal\express-engine\bundles\express-engine.umd.js:110:29 at new ZoneAwarePromise (C:\project\node_modules\zone.js\dist\zone-node.js:910:29) at getFactory (C:\project\node_modules\@nguniversal\express-engine\bundles\express-engine.umd.js:96:16) at C:\project\node_modules\@nguniversal\express-engine\bundles\express-engine.umd.js:75:17vikerman commentedon May 24, 2019
We have a fix to the ng add schematics for 8.0 for this.(PR above)
But to manually fix your existing project - Move all Angular related imports in server.ts as re-exports in main.server.ts and then you can use --bundleDependencies all. Would also need to change the top-level webpackconfig to main.ts external to server.ts builds.
Shown in example repo here -
vikerman/v8-lazy@515239b
With this you should need to deploy only dist/server.js and dist/server/main.js and not node_modules.
vikerman commentedon May 24, 2019
@dominikfoldi @stefankip - can you try the suggestion above?
dominikfoldi commentedon May 24, 2019
@vikerman our Angular project is not ejected so I cannot modify the webpack.config. I can wait until Angular 8. Glad to hear that you have a fix!
vikerman commentedon May 24, 2019
@dominikfoldi - Not sure what your setup is. But essentially the fix would be to move all references to @angular and @nguniversal to the main.server.ts and bundle it once there and use only re-exports from the express(or whichever) entry point. Otherwise you would end up with two copies of Angular and things will start to fail randomly.
ErazerBrecht commentedon May 26, 2019
@vikerman
I can confirm the 'fix' works ;)
The only problem is that I now have the original error:
Like already said in this issue disabling optimization fixes this.
I'll do this for now until this issue is completely fixed
Again thx for your effort & the example repo
stefankip commentedon May 28, 2019
@vikerman awesome, works perfectly! Thank you very much!
vikerman commentedon Jul 30, 2019
Closing this as we have some reports that this works.
naveedahmed1 commentedon Aug 9, 2019
@vikerman I think the issue still exists
"bundleDependencies": "all",works only when"optimization": false,but when"optimization": true,it throws below errornaveedahmed1 commentedon Aug 26, 2019
@vikerman how about this #8616 (comment) ?
naveedahmed1 commentedon Aug 31, 2019
Ok I have found one solution.
"optimization": false,inangular.jsonfile."bundleDependencies": "all",inangular.jsonfile.npm run build:ssr). This will generate a large bundle., in my case the size of the bundle is 9.89Mb with IVY Enabled.npm install terser -gterser dist-server/main.js -o dist-server/main.js -c -m --keep-fnames. The compressed build in my case is of 3.9mb i.e. ~60% reduction.Please do share feedback and suggestions for further improvements.
angular-automatic-lock-bot commentedon Oct 1, 2019
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.