Skip to content

Easy "ng build" improvements to make "platform":"server" work well on Windows & Visual Studio #7903

Closed
@SteveSandersonMS

Description

@SteveSandersonMS

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.

Metadata

Metadata

Assignees

Labels

featureIssue that requests a new feature

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions