Description
I work on the ASP.NET team and am looking at changing the default Visual Studio ASP.NET + Angular templates to be based around Angular CLI. One thing that's stopping us right now is issues with publishing and deploying such Angular CLI apps.
Basically, for ng build
to work well with Universal on Windows/VS, it's essential for it to have an option to produce self-contained builds, i.e., ones that don't rely you to deploy node_modules
to your production server.
Why this is needed
Originally, the default official ASP.NET templates for Angular, which have server-side rendering on by default, expected developers to deploy node_modules
to their production servers. This led to many, many issue reports, because it turns out that from Windows, people cannot deploy node_modules
reliably. This isn't really developers fault. Two basic problems:
- On Windows, path length limitations mean that MSBuild fails to publish deep nested folder structures, such as those that appear in
node_modules
. - Visual Studio's MSDeploy mechanism processes every file one-by-one quite slowly, so trying to deploy 20,000+ files from
node_modules
is a process that has you waiting for an hour and very frequently will fail with a network-related error eventually.
So in the default ASP.NET Core Angular template, we solved this by changing the default Webpack config not to treat node_modules
as a Webpack external
, causing Webpack to bundle all the server-side rendering dependencies into its single bundle output file. That output file is then large (4MB+) but that's OK: people can reliably deploy one 4MB file, as opposed to 20,000 tiny files. And it's only used server-side - this file is never sent to browsers.
Now we'd like to change the default Visual Studio ASP.NET templates for Angular to use Angular CLI, but we can only do this when the resulting projects can be published and deployed reliably. And that means a self-contained build option.
Fortunately, the implementation for this in Angular CLI is pretty much trivial - see below.
Bug Report or Feature Request (mark with an x
)
- [ ] bug report -> please search issues before submitting
- [x] feature request
Versions.
1.4.2
Repro steps.
If you run ng build
to build an app configured with "platform":"server"
, then observe that the resulting dist
directory's bundle files are not self-contained. That is, they only include the application's own code - they don't include the @angular
code from NPM or any other required packages. The only way it can work at runtime is if you have node_modules
on your production server, which causes great difficulty in practice as described above.
Desired functionality.
Ideally there would be an option for the "platform":"server"
builds to be self-contained - i.e., can run without any node_modules
, simply by not telling Webpack to treat those files as externals
during the build. The use cases is to simplify publishing and deployment, especially on Windows/VS.
Mention any other details that might be useful.
This is pretty simple to implement. In server.ts from line 13, we see the Webpack config for externals
used in server builds. All we need is a build option that disables this, i.e., leads to the externals
array being left empty. Then Webpack will produce completely self-contained bundles that work correctly without node_modules
being on the production server.
One minor complication is that, for some reason, Angular CLI tries to minify (via uglify) the server-side bundle in production, which leads to a build error with self-contained bundles. I recommend that server-side builds should not minify by default, because (1) that will fix the error, and (2) who wants to minify their server-side code anyway? It's much easier to understand/debug unminifed server-side code. If necessary this could be another option, but I really think it would be enough just to avoid minifying server builds altogether.