When starting a new project with Angular you most likely will be faced with a choice whether to use Angular CLI or go with a custom Webpack setup (perhaps, using one of the available Webpack seeds available).
In this post I would like to examine pros and cons of those two approaches and share my experience with this choice.
If you are looking for a quick advice, then I would say go with Angular CLI until you discover a good reason to switch to custom Webpack config, at which point you can easily switch using Angular CLI's eject button.
In my opinion the biggest and most important "feature" of Angular CLI is that it makes your project future proof in regards to how your code is bundled/packaged for the web by abstracting away the underlying tools and configuration details.
Additionally, consider this quote from a comment by a member of the CLI team:
The major goal of the CLI was always to abstract away the underlying systems, and reduce the "framework fatigue" due to making (in the end inconsequential) decisions that require vast amount of knowledge of the ecosystem. If you're an unexperienced developer that's looking to start in Angular, this is the best tool so far...
I personally can relate to the problem of "framework fatigue". The amount of stuff that one needs to know to start with a simplest project is staggering. Therefore, I do believe that Angular CLI should be your first choice when you start a new Angular project.
In addition, Angular CLI has some other features, like code scaffolding, but I find these to be somewhat less important when making the decision whether to use Angular CLI or not.
Having said that, let's see why you might want to switch to custom Webpack setup or start with it from the beginning. In fact, this is exactly what we had to do in our project at independer.nl.
Custom Webpack Setup
The biggest advantage of Angular CLI is also its greatest weakness. One the one hand, it hides all the complexity of Webpack providing us with a simple declarative way to configure our application with
.angular-cli.json. This approach works very well when you have a relatively small application with fairly standard bundling requirements. It lets you spend as little time as possible configuring your build tool chain and allows you focus on the features of your app instead.
On the other hand, with Angular CLI you also give up certain degree of control over the way your application is bundled. Angular CLI is a one-size-fits-all solution. It tries to satisfy the needs of a wide range of web applications, and sometimes, especially when the project is very large, this gives suboptimal results.
As soon as you need to go beyond standard configuration and need to meet unique needs of your application you will quickly hit the wall with Angular CLI. Here are a few examples from our experience at independer.nl:
- Multiple apps. We have a large website/application with multiple distinct "areas" that need to share code. Angular CLI does support defining multiple applications in the
.angular-cli.json, but all the CLI commands work only with one app at a time (e.g.
ng build --app <app-name>,
ng serve --app <app-name>, etc.). In our case, that didn't work very well and we needed to build/serve everything together.
- Slow builds. Due to the sheer amount of code, the builds became very slow. We were able to significantly cut down the build times by introducing Webpack DLLs for third-party libraries and parallelizing Typescript compilation using HappyPack (see Faster Angular builds with HappyPack to learn more).
- Server-side rendering (Angular Universal). Angular CLI supports Angular Universal already, but this support was added very recently, while we needed it long before. This goes to show that, even though the support for certain capability is eventually added to the CLI, it might come with significant delays.
These are examples of bigger things that we ran into. There are also numerous smaller, not so critical customizations that we needed to do in our project.
Side note: If you're curious how exactly we tackled the above, check out ind-angular-starter.
That said, being able to fully customize your build tool chain comes with a price. Webpack is known for its steep learning curve and I can certainly attest to it. I've spent countless hours experimenting with different loaders and plugins, battling with weird errors, keeping up to date with a gazillion NPM packages, etc. This stuff is not easy and requires quite a lot of effort to make sure your Webpack build infrastructure is and stays optimal.
Angular CLI is, at very least, a great starting point. It lets you focus on the most important thing - logic of your app.
However, be aware of its inherent limitations - being an abstraction and simplification of the underlying build systems. As soon as you need to do something that is not very common, the chances are that you will need to switch to custom Webpack config.