Angular – one year usage summary


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 with Angular 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, replace CSS with SASS), but you don’t need to configure webpack 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 of AngularJS 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 when Angular 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 even Angular 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 like React's setState. It’s easy to understand, track and debug, you can use it in any case (e.g. with setTimeout and it will work properly, but OnPush 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 without jQuery UI under the hood;
  • Choosing RxJS as a main technology for handling server calls in HTTP module and @ngrx state management. I cannot say, that RxJS 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 simple Promises or async/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 use async pipe in your templates and OnPush change detection strategy;
  • Choosing TypeScript as a main language for writing Angular applications. And here is quite similar situation to RxJS with the only difference that TypeScript is much easier to master than RxJS. 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. And JavaScript was a language just for me. A lot of people say that TypeScript brings safety to your code, but I cannot agree with this statement. I’ve never seen developers who do not understand the data flow in JavaScript and can assume incorrect type. I’ve never seen critical production bugs in pure JavaScript applications caused by calling method which doesn’t exist on the referred object. So again, I’m not saying that TypeScript 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 use any keyword a lot. So I’m pretty sure that for most of the front-end projects TypeScript 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!

2 thoughts on “Angular – one year usage summary

  1. 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…

    Liked by 1 person

Leave a Reply to Anton Gorbikov Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s