Sign in

Implementing Angular’s missing “delete output path after build” option

Image for post
Image for post

If you fancy it, check out the same post on my personal blog.

If you’re like me and you build your Angular apps in the default output path and serving it from there, then you’ve probably run into the following issue: downtime during the build process which can, for large apps, take more than 2 minutes.

Joke aside, you may be able to overcome this with some nginx Apache caching wizardry or with some fancy CI/CD pipeline, but I’m interested in a solution that works for the out-of-the box setup which I believe many apps out there are using.

Frankly, it’s a mystery to me why this is not the default behavior of ng build.

The problem

For those of you who read so far but don’t know what I’m talking about, first of all, thank you, you’re awesome.

I’m talking about the fact that when you build your Angular app, it first deletes your output path, then builds your app and saves it in the output path. Therefore, any new users who don’t have your app cached will be served a 404 error while the app is being built.

Yes, I know, I can set the --delete-output-path to false and quit whining, but that will not delete the old assets, it will keep adding new files for every build, which probably works for most people, but I can't sleep at night like that.

Read along if you:

  • are building your Angular app on your deployment machine
  • are building your Angular app more than once (e.g. you expect to implement new features / push fixes in the future)
  • care about downtime
  • care about not polluting your server with hundreds of useless past builds
  • like reading stuff just for the sake of it

After getting confused by this stack overflow post and this blog post, I decided the only way to accomplish this is to build it myself.

The solution

I decided to write my custom build script that wraps ng build in node (note that this could have been done in pretty much any scripting language).

First thing I did is put down a simple step by step plan for this script:

  1. Build the Angular app in a temporary directory (I chose dist/aux)
  2. Delete the default output path
  3. Move the temporary directory to the default output path

Then I realized I’m probably going to want to write a blog post about this and I wanted it to be at least decent, so I decided not to hardcode the output path, but read it from the angular.json config so you guys (and girls) can just copy paste it into your project and BOOM, never have your users experience downtime again!

So, step 1b. read the default angular output path from angular.json.

Since we’re going to be spawning new processes and want to be politically correct to all OS owners out there, I decided to use the cross-spawn package. Add it to your build using your package manager (I’m using yarn just to be like the cool guys who take the extra step to install it to differentiate themselves from the normies who use the perfectly fine default option, npm):

yarn add cross-spawn --dev

I’m not going to take you step by step through the code (like all the other annoying Medium posts), since by this point you’ve probably scrolled down looking for the code snippet or link to git gist to just copy and be done with this bullshit. So here it is:

If you’re sporting the vanilla Angular setup, you probably have these scripts in your trustworthy package.json:

"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
...
},

I also have two more handy scripts in there, for my two deployments:

    ...
"build:staging": "ng build --configuration staging",
"build:prod": "ng build --prod",
...

You’ve probably left by now, but just for the sake of SEO, I’ll keep going.

You probably want to replace your build script(s) with the newly found wisdom, which I saved into a file called build.js and placed it in the root of my project.

I replaced my scripts with the following:

    ...
"build:staging": "node build.js --configuration staging",
"build:prod": "node build.js --prod",
...

Instead of calling ng build, we're calling build.js. You can plug in your own parameters (if you had others), since the build script will pass those further to ng build.

Conclusion

There you have it folks, a way to manually implement Angular’s missing “delete output path after build” option.

Now you can sit back and enjoy building your app again and again without worrying about downtime for your users.

Written by

Software & Machine Learning Engineer. I love building products that deliver value & happiness! https://constantin.al

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store