If I could sum up Angular’s strengths in one word, I would choose “engineering.” If I had to change to a more artistic word, I would say, “The great coincidence works, the road is simple.” The framework, created by a group of Google engineers, was clearly “engineered” from the start.

What is engineering development? It’s the opposite of artisanal development. The main feature is the need for multiple people, multiple hours of work and coordination, rather than one super programmer writing 90% of the code, the others only do the help.

But the challenges faced by medium – and large-sized systems cannot be solved by superprogrammers. If the complexity of a system accumulates, sooner or later it will become more and more expensive to maintain and become a chicken rib. The first way to solve complex problems is to isolate the parts of the system at an architectural level so that they are independent of each other, that is, divide and conquer, divide and conquer. But it won’t be easy.

collaboration

One of the biggest challenges in multiplayer development is how to work together.

In Angular, the main infrastructure used to support collaboration is modules.

For example, if we do not define the hard boundaries of the application through modules, the component written by A may reference the component written by B, but B wrote this component for its own use, without considering reuse. Then the work between A and B creates accidental coupling, and accident is engineering’s biggest enemy. As it turns out, unintended coupling in all its forms tends to lay mines.

With modules, B can hide the component from others so that components written by A can no longer inadvertently depend on components written by B. If the parties reach a consensus in the future, they can collect the requirements of the parties and develop a new component for the purpose of reuse, rewriting the original component into this reusable component and adding some adaptation code.

Now it is finally possible to assign a clear “responsible person” to each module instead of “controlling the water in Kowloon”. At the same time, the division of teams has been optimized, with a small number of experts working on reusable and core modules, and novices working on modules that are “solely responsible for themselves,” regardless of the quality of the code they write, at least without exacerbating these problems. Getting everyone to do their best is the boss’s favorite trait, and it’s a sign of your organizational and managerial skills.

In addition to the problem of unexpected coupling, another challenge of multiplayer development is the contract.

Manual development may not require an explicit contract, because the superprogrammer is “cosmic” and knows every key point of the system. But once there are too many people, the drawbacks of this approach become apparent. After all, human minds are not connected. In this case, contracts need to be explicitly described, with tools to ensure that they are not misunderstood.

In Angular, the main infrastructure for dealing with contract issues is types and tests.

Angular uses TypeScript to support types. With types, Angular can express the interface contract to a certain extent. For example, if I only want you to pass me a number and not a string, I can define this parameter as type number. If the caller passes a string, the error can be detected and prevented at compile time. We all know that the sooner a mistake is discovered, the cheaper it is to fix. Of course, TypeScript’s type system is far more powerful than that, and Angular, as the primary practitioner of TypeScript from birth to maturity, takes TypeScript’s features to the extreme. This is a very large area, so I won’t go into it here.

However, a type can only say so much about a contract, but it can’t say something like “I want a number greater than 10 and less than 1000,” where different levels of testing are needed. Testing has been a priority since the earliest AngularJS, let alone the Angular rewrite. Not only does Angular have high test coverage for its own code, but it also provides full support for writing your own tests. You can easily and quickly test standalone functions/classes that don’t depend on Angular, easily test Angular services, etc. You can also midway test components to verify that they generate DOM nodes correctly. Without resorting to heavier methods such as E2E testing. Also, don’t forget that Angular services, components, pipes, and so on are pure classes (POJos). The annotations attached to them differentiate them into different uses without changing their nature as POJos. You can also use them as Angular independent POJos for extremely fast testing. With this level of testing support, you don’t have to worry about “can’t test” at all, you just need to worry about which testing method is the most appropriate for a certain situation, and that’s where you can make the most difference.

A slightly easier but more tedious issue in multiplayer development is code style.

“Writing like one person” can be quite troublesome for a team to develop a uniform code style, especially if there is turnover on the team. It is useless to formulate code specifications alone. “norm.exe” is better than “norm.txt”. A common practice in the industry is to rely on the Check Style tool, usually called Lint in the JS world. But Lint doesn’t know the specific framework, so it can only guarantee framework-independent code specifications, not large frameworks like Angular.

The Angular development team thought of this and created a tool for Angular style checking that was integrated into the Angular CLI. The specification it is based on is the official Angular style guide provided by the Angular development team. With this style guide, Angular programmers from all over the world, foreign countries, and now and tomorrow can write code that looks pretty much the same. Of course, your team can adjust the style checking rules as needed, but if you are not a very experienced Angular team, you are advised to stick to the default values.

Time is the system’s biggest customer and its biggest enemy.

One that prints Hello, world! And write a program that doesn’t require any engineering. Real systems evolve over time, and the longer they are used, the more they are accepted, but on the other hand, the longer they are used, the more likely they are to decay, until they “kill” the system.

How does Angular resist age

First, Angular is designed to focus on one thing per part (separation of concerns SoC).

At a macro level, the Core module provides infrastructure like dependency injection, the Forms module provides forms support, the Router module provides routing, and so on. This clear division gives Angular the seemingly contradictory qualities of big and whole and small and beautiful. Small and beautiful ensures that the system uses as few Angular modules as possible to avoid the impact of changes to other modules. Large and complete ensures that the system can do a lot of things even with modules provided by Angular itself, and minimizes the erosion of third-party dependencies.

At the micro level, services split out state and logic that is global and shared across multiple components, but it doesn’t care about interface presentation at all. A component is only responsible for presenting the user interface, and some of its own logic can be delegated to a service; Directives are only responsible for simply extending the capabilities of DOM elements or existing components; Pipes are only responsible for the transformation from model data to display data. With a clear division of labor, the impact of requirements changes is minimized.

Second, Angular’s release strategy strikes a good balance between maintaining stability and embracing change.

In fact, this versioning strategy is not unique to Angular; it’s called semver. Heavyweights like NodeJS and the latest Java have followed this strategy.

The point of semantic versioning is that only backward-incompatible changes are introduced when major version changes are made, minor version changes only add backward-compatible new features, and revision changes only fix bugs in a backward-compatible manner. The point here is that “backward compatibility” only occurs when the major version number changes.

Adopting this publishing strategy requires a lot of engineering skills that the average author can’t easily do, but the Angular team believes in it and is delivering on its promise. In fact, the Angular team does more than that: every major version of Angular is fully compatible with the last major version, but it flags the incompatibables as a warning, giving you six months to make changes. The Angular CLI also provides the Update command, which automatically updates your application from the previous major version to the current major version. I once upgraded an Angular application from 5.0 to 6.0 in two minutes that took one person a month to develop.

Semantic versions have the benefit of being able to both grow the ecosystem and pursue new technologies. Ecosphere likes stability, and you don’t want to write a library that will become unusable in half a year, or even if it does, you don’t want to spend a lot of time migrating just to keep up with the new version. But keeping up with the cutting edge is a fundamental guarantee of a technology’s longevity. And real engineering, you want both, you can’t lose either.

Finally, Angular is both old and new.

It’s old because Angular uses a number of mature technologies that are decades old, such as dependency injection, interfaces, annotations, and so on. These are all best practices that have stood the test of time, and since they have not been eroded over the years, it can be expected that, barring revolutionary changes in the future, they will remain untouchable. To their credit, Angular never invented a new noun to wrap them around, as the front-end circle probably loves inventing new nouns.

It’s new because Angular embraces other upstream and downstream technologies and follows standards. From its initial choice to work with TypeScript as a teenager, to its deep integration with RxJS, to its early support for PWA, to its adherence to standard drafts like Web Components, Angular is open and up-to-date.

conclusion

The essence of engineering is to support team-based development and help systems resist the erosion of time, and Angular shows the beauty of engineering that makes me optimistic about the future of Angular.

Although Zhou is an old state, its destiny is reform!