When you are starting the new project you probably facing an issue of picking up proper technical stack. There are dozens of frameworks (Angular
, Vue.js
), libraries (React
, RxJS
, lodash
), tools (webpack
, gulp
) and even languages (JavaScript
, TypeScript
, Reason
) available for front-end developers. At this point of time most of the developers are starting to search information, comparison articles in the Internet. I’ve been working with the Angular (a.k.a. Angular2+) for last year and I want to share my thoughts about my personal experience.
Pros
- Amazing infrastructure and tools. I’m talking about
@angular/cli
of course. This tool is very good and it’s especially useful on the early stages of the project, when you are not familiar withAngular
style guides, recommended folder structure, etc. Using this tool you can scaffold your project, which will include root module, component, configuration for end-to-end tests and unit tests. Moreover, there are useful commands to create new components, modules, services, etc. These commands will write some boilerplate code for you and register new code where it’s required. And last but not least,@angular/cli
provides new high-level configuration, which let you change some parts of the build process (for example, replaceCSS
withSASS
), but you don’t need to configurewebpack
manually and waste hours and hours to adopt build for your new project; - Documentation. It’s not perfect as usual, but it’s quite good. It’s a really good starting point where you can find basic patterns, get understanding of proposed application architecture. The good thing is that it’s updated regularly, community creates issues if documentation contains mistakes, typos, missing new functionality or contains deprecated information. So it’s really good starting point for newcomers. Also, this documentations contains style guide, so if the team is using this common style guide it’s possible that switching from one
Angular
project to another can be very easy; - No performance issues. It’s not very important point nowadays, because most of the competitors have amazing performance. But
Angular
has a legacy ofAngularJS
and this framework has a lot of issues with performance and you can still find a lot of projects which are using this framework or trying to migrate. So don’t be confused, these are two different frameworks, they have different architecture and the new one is stable and fast; - Custom linting tool. I’m talking about
codelyzer
. It’s installed by default if you are using@angular/cli
so you won’t miss it. It’s cool to have linting tool with most common pitfalls and mistakes made, especially when you are new to the technology or when you are working within big and distributed team; Angular
is supported by Google, which means it’s regularly getting updates, new features, etc. It is very important for long living enterprise projects;- And one more cool feature is the template type check. At first glance you may think, that there is no way to check missing/redundant function parameters, typos in properties, however there is a way and it’s working (at the time of writing this article it was disabled by default). It’s is strictly recommended to enable this option, it’s very handy when you’re refactoring some code which affects rendering. It’ll make you feel a bit more confident. Also it will show some errors, which are not detected by Ahead-of-time compiler because of bugs.
Cons
- The ability to use
@angular
and@angular/cli
as a big black box product is an advantage and a disadvantage at the same time unfortunately.Angular
has a dozens of direct and hundreds of indirect dependencies under the hood. Of course whenAngular
team updating dependencies there is a huge risk of regression, especially in CLI updates. You have no control over all dependencies so you cannot downgrade just one buggy dependency and proceed. Most of the time you are downgrading the entire CLI and sometimes evenAngular
itself, because they are tightly coupled to each other. Let me bring you couple of issues I’ve faced personally: I cannot build my project and produce ES2015 compatible output because of some issues in uglifier (you can say that it’s not critical and you are right, but ES2015 bundle is smaller than ES5 bundle, resulting in better performance), there is still an issue with building fonts in Angular applications, it’s not resolved for a couple of months (to fix it in my application I’ve changed fonts usage in 60+ components); - Some critical parts of documentation are missing all the time. Let me bring up simple sample I have in my mind right now. I know 2 projects which were started at the beginning of
Angular
lifecycle and both of these project at some point faced issue with bootstrapping performance. After short investigation they found that Ahead-of-time compilation is disabled by default in production mode. And the interesting part they were not aware about some additional constraints which AoT compiler creates for code base. As a result they’ve spent additional time to align code base with these constraints, perform a regression testing and find flags which can validate these constraints on the regular basis as a part of CI build process; - Change detection mechanism. Personally I don’t really like technologies which are easy to use but hard to master and fully understand. And in my opinion change detection strategy or mechanism is that kind of technology. There is no official documentation which explains every detail of this mechanism – it’s just working. But at some point of time you’ll find that there is a more performant way (I mean
OnPush
strategy) of managing changes in your application. But to use it properly you’ll need to read at least a couple of articles in the Internet to understand cases where it’s applicable. And still you’ll end up triggering change detection manually in some components or in some specific cases. Personally I prefer something more straightforward likeReact's setState
. It’s easy to understand, track and debug, you can use it in any case (e.g. withsetTimeout
and it will work properly, butOnPush
change detection strategy will not); - Limited set of available components libraries. Official
Angular Material
contains only few important component, like datepicker or slider. And I didn’t find any good components library with big amount of available components and withoutjQuery UI
under the hood; - Choosing
RxJS
as a main technology for handling server calls in HTTP module and@ngrx
state management. I cannot say, thatRxJS
is bad or buggy because it’s not.RxJS
is a very powerful tool and I’m pretty sure that there are a lot of cases when you can write code in more elegant way than with simplePromises
orasync/await
. But in many cases it’s a simple overkill. There is no way to retrieve latest value of the stream because stream doesn’t store it. You need to merge streams all the time and in my experience at some point of time code becomes over complicated. And because we are talking about front-end applications and streams on front-end you always have two different directions of streams: from user and from store/server. And at some point you need to validate user input using values from store/server. If you make mistake (and you’ll do it, it’s just a question of time) you’ll end up with circular references in streams. So again,RxJS
is a very powerful thing, but in most of the project I’ve seen so far nobody uses it’s full power. So my personal experience that it’s over complicated and redundant in most of the cases. You can, of course transform all streams to promises, but as a downside you’ll not be able to useasync
pipe in your templates andOnPush
change detection strategy; - Choosing
TypeScript
as a main language for writingAngular
applications. And here is quite similar situation toRxJS
with the only difference thatTypeScript
is much easier to master thanRxJS
. I know all the benefits of strictly typed languages I have.NET/C#
background but at some point of time I’ve decided that I want to concentrate on writing business logic and data management. AndJavaScript
was a language just for me. A lot of people say thatTypeScript
brings safety to your code, but I cannot agree with this statement. I’ve never seen developers who do not understand the data flow inJavaScript
and can assume incorrect type. I’ve never seen critical production bugs in pureJavaScript
applications caused by calling method which doesn’t exist on the referred object. So again, I’m not saying thatTypeScript
is a bad technology, it’s just not for everyone. I’ve to add a lot of redundant code, describe all entities which I use, etc. And I saw in the several projects that people getting tired of it (even.NET
developers who are working full-stack) and useany
keyword a lot. So I’m pretty sure that for most of the front-end projectsTypeScript
is an overkill with a questionable benefits.
Conclusion
That’s all I wanted to share. I wanted to remind that’s only my personal opinion based on my personal experience, experience of my colleagues and code bases which I reviewed. But in general my vision is that Angular
is a good choice for huge enterprise applications with hundreds of components and dozens of pages. For middle-size or small applications I’d suggest to take a look at something more flexible. Thanks for reading!
That is very thoughtful article Anton. Thank you :).
I share a lot of ideas with you.
I’ve used Angular 2+ coupled with RxJS and ngrx/store.
I’ve investigated RxJS rather deep https://www.youtube.com/watch?v=0Cl6vpZ9oLM.
Indeed RxJS demands to change the way of thinking and though that may be reasonable for complex projects that doesn’t make sense for simple cases.
So introducing RxJS into the transport layer like is not good solution I think. Such approach enforces average developer just to do immediate subscription to the http stream instead of deriving other streams and moreover that is just recommended way according to the basic Angular guidelines…
Why if usually RxJS is not used properly it was necessary to create dependency to it on the transport layer? It would be more reasonable just use promises and keep RxJS for that developers who really understand it and would like to use. It is easy to derive RxJS stream from promise…
Another thing I don’t like in Angular is own module concept. It creates a parallel concept to the es6 modules. And just make solution more complex and fragile because it may leads to the runtime errors due to some provider just not specified.
What is the reason of Typescript usage if runtime errors are still very possible?
Why if module is developed no compile time checking is developed?
In general I don’t like an IoC idea because it creates monsters.
Because RxJS is very functional concept it doesn’t very good work with modules and services. RxJS streams are much more small items than service and if speak frankly they just don’t need any service to live. If define streams in service it creates a risk of circular dependencies between different modules if do it in the component it just breaks reusability of streams…
LikeLiked by 1 person
Thanks for sharing, very good addition to my thoughts!
LikeLike