GeezerVison is showing github.com — SSR builder and externals dependencies (Angular 9) · Issue #16348 · angular/angular-cli
SSR builder and externals dependencies (Angular 9) #16348DescriptionBug Report
In relation to the conversation with @manfredsteyer.
What is the expected behavior?
In some specific scenarios, I would like to bundle dependencies and minify the code of my Angular application, but at the same time leave my server-side code untouched (no dependencies bundled, no minification/obfuscation). This is important because:
- sometimes you may not want to bundle all server dependencies (especially when you're building a full-stack app). For instance, you won’t be able to bundle
pg (if you use postgres) as well as internal deps of mongoose (or bcrypt) because they use a native node.js binaries (C++ code)
- sometimes you may not want to obfuscate class names, properties names, function names etc because there are important for libraries such as Typeorm (to automatically create columns with proper names in a database) or e.g. NestJS. Having full control over what can be optimized for server-side is quite important here
What is the current behavior?
When I try to set bundleDependencies to none under server configuration in angular.json, the application will stop working:

Both serve:ssr and serve:ssr:dev won't work.
Also, I'm not entirely sure how I can determine the behavior of webpack for the server part now. Previously, we had webpack.server.config in which we could simply use plugins like nodeExternals or set optimization to false (to avoid code minification). This is worth adding to the docs (how to accomplish this now with a new setup).
What modules are related to this issue?
- [ ] aspnetcore-engine
- [ ] common
- [ ] express-engine
- [ ] hapi-engine
- [ ] module-map-ngfactory-loader
Minimal reproduction with instructions:
No reproduction needed - new Angular app with ng add @nguniversal/express-engine@next (or any other engine)
What is the use-case or motivation for changing an existing behavior?
Mainly full-stack applications, compatibility with other Node.js platforms
Environment:
@nguniversal versions
- aspnetcore-engine:
- common:
- express-engine: 9.0.0-next.7
- hapi-engine:
- module-map-ngfactory-loader:
Angular CLI: 9.0.0-rc.4
Node: 12.13.0
OS: darwin x64
Angular: 9.0.0-rc.4
Is there anything else we should know?Activityalan-agius4 commented on Dec 4, 2019 Hi, this is expected unless 'node_modules' are transformed using the standalone Angular compatibility compiler (NGCC).
See: angular/universal#1327 (comment) for more context and how to address this. kamilmysliwiec commented on Dec 4, 2019
- Disable server dependency bundling which can be done via the angular.json configuration. Under your server target options add "bundleDependencies": "none"
- Run NGCC binary prior to building. This can be done by adding a postinstall script in your package.json - "postinstall": "ngcc"
Following the above steps fixed the issue, thanks!
Nonetheless, I still can't find a way to apply a custom webpack configuration to both build:ssr (for prod) and serve:ssr:dev scripts. I want to leverage builders to avoid using three different scripts (as in Angular <= 8), have a live reload built-in and at the same time, have an ability to adjust ts-loader configuration (e.g. apply plugins) and externals dynamically from js file. Is it possible? kamilmysliwiec commented on Dec 4, 2019 Also, since adding postinstall script, manually removing & reinstalling all packages and setting bundleDependencies to none isn't straightforward, I'd suggest adding an option to the ng add UNIVERSAL_ENGINE[?] schematic that would perform all these tasks automatically (e.g. --no-bundle-server?).
This is, in fact, very important for everyone who wants to not only serve SSR Angular app but also create, for instance, a basic REST API that connects to a database. With current setup (without manually performing all changes listed above), the following stack: express/nestjs/koa + Angular SSR + postgres/mongoose won't work properly. alan-agius4 commented on Dec 4, 2019
Nonetheless, I still can't find a way to apply a custom webpack configuration to both build:ssr (for prod) and serve:ssr:dev scripts. I want to leverage builders to avoid using three different scripts (as in Angular <= 8), have a live reload built-in and at the same time, have an ability to adjust ts-loader configuration (e.g. apply plugins) and externals dynamically from js file. Is it possible?
To achive this you'd need to replace the @angular-devkit/build-angular:server builder with a 3rd party builder that allows such behaviour.
This is, in fact, very important for everyone who wants to not only serve SSR Angular app but also create, for instance, a basic REST API that connects to a database. With current setup (without manually performing all changes listed above), the following stack: express/nestjs/koa + Angular SSR + postgres/mongoose won't work properly.
Can you elaborate please to why this doesn't work properly? Is this because @nestjs/ng-universal requires a bundle as an external file? kamilmysliwiec commented on Dec 4, 2019
Can you elaborate please to why this doesn't work properly? Is this because @nestjs/ng-universal requires a bundle as an external file?
It's not about @nestjs/ng-universal. Even with a default configuration and the @angular-devkit/build-angular:server builder, NestJS itself will work fine.
The problem starts when you would like to create a real-world full-stack app with Angular SSR, regardless of whether you're going to use either express or NestJS or anything else.
Once you try to "bundle" your app which consists of Angular, Express and MongoDB, you will see the following error:
Error: Cannot find module './drivers/node-mongodb-native/connection'
at webpackEmptyContext
Why? Because mongoose depends on mongodb which depends on kerberos (C++) and node-gyp.
Similarly, if you try to build an application which consists of Angular, Express, and Postgres (with, let's say, TypeORM as ORM), you will see this error:
ERROR in ./node_modules/pg/lib/native/client.js
Module not found: Error: Can't resolve 'pg-native'
Why? Because pg depends on pg-native which depends on node-libpq (low level C++ native bindings to PostgreSQL).
Lots of popular Node.js packages that are "required" to build a typical REST/GraphQL API depend on native bindings. With the current (default) configuration, this builder will be useless for most people who want to do more than perform server-side rendering. alan-agius4 commented on Dec 4, 2019 I see what you mean now, maybe we should also users to specify externals in an easier manner. I'll move this to the CLI repo since that is where the server builder resides.
We'll have a chat around this in our next team meeting and we'll decide if we should support this out-of-box or rely on 3rd party builders to allow specifying externals. added a commit that references this issue on Dec 6, 2019This issue will close once commit 6f4fef5 is merged into the 'main' branch.6f4fef5 angular-automatic-lock-bot commented on Jan 6, 2020 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. added a commit that references this issue on May 29, 2026This issue will close once commit fb57eed is merged into the 'master' branch.fb57eed
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|