In the past, like most engineers, I assumed that the level of front-end code design was mostly directly related to the ability of the engineer. But as I’ve worked on several large, multi-player front end projects, I’ve come to realize that while this may be true for small projects with short life cycles, for really large projects, improving the quality of the engineers alone sometimes doesn’t directly improve the quality of the code.

This article will combine some of my practical experience to illustrate my point of view: to build a large high-quality front-end project, reasonable code constraints and correct team operation mechanism may be more important.

What is high quality engineering code?

High quality engineering code is not the same as the best performance, the latest technology, the most reusable technology selection. Looking back a few years at the front end: in the jQuery era, you had to work with the DOM by hand, but back then, Google Closure and the Ext.js team provided a full concept of componentization, and even Ext.js provided innovative event mechanisms such as component bubbling. The code maintained with Zepto back then was even faster than writing some React projects today. Different technologies are just tools, and how and to what extent you use the tools is ultimately up to the developer, so quality engineering code should be considered more from a business and engineering perspective than from a technical selection perspective.

For example, when the entire company was developing with React, we knew that Vue would be easier to use, but we didn’t use it because it looked easier to write code, but you couldn’t reuse what other people had learned from React. In addition to requiring the entire team to learn a whole new set of techniques, such engineering design, in this context, is clearly not reasonable.

TheNewStack looked at developer statistics for 2019 and found that developers spend 32% of their time on business development and 19% on code maintenance, which means engineers spend only half as much time on development as they do on the job. For developers, reasonable code design at this time to improve code scalability, maintainability, reduce the time to develop and maintain the code, is the strongest appeal.

Therefore, high quality engineering code should be combined with the business and team situation, which can really improve the R&D efficiency and reduce the maintenance cost of the project.

Who determines the quality of the project code?

Here’s an analogy with the barrel theory: The water level in a barrel depends not on the highest plank, but on the lowest. Similarly, the quality of a front-end project is determined not by the average capability of the team, but by the ability of the less experienced technical classmates on the team. In the case of high work pressure, these students, due to lack of experience and short term needs to complete the requirements, so most of the time, they did not consider the engineering problems, but directly oriented to the implementation of functional programming, basically we are now facing difficult to maintain the code, are generated under such conditions.

Of course, we can hope that the less experienced students can improve the quality of the project through continuous growth, but in practice, this is not feasible. The reason is that the accumulation of engineering ability requires a lot of coding experience, and the problem of lack of practical experience cannot be quickly solved in a short period of time. Any good engineer grows in the process of constantly making mistakes and learning. At the same time, the project development process is likely to encounter personnel changes, a team members are not always able to be strong.

Then we need to change a strategy to ensure the quality of our code. We can think about it from another perspective: whether it is possible to make engineers with different coding abilities write relatively high quality consistent code through some rules, processes and coding constraints.

Improve project quality through constraint

Constraints make things easier

Without constraints on our work, it is difficult for us to form consensus and judge whether our work is good or bad. The same goes for writing code, there are no constraints, so we can’t judge whether the code is reasonable or not. Constraints are everywhere in popular libraries and frameworks. Take the design of Redux and React for example:Redux presents the three basic principles of single data source, State read-only, and using pure functions to implement modification. Meanwhile, it requires to trigger the implementation of Reducer through Action, which is the constraint of Redux. React also gives the concept of constraints such as one-way data flow.

Frameworks are reusable and generalizable because they are encapsulated and provide only limited constraints for everyone to use, so that everyone can come up with the same ideas and write code that each other can read. With this in mind, let’s look at the business engineering code and see that the only way to improve development efficiency and scalability is to provide reasonable constraints.

Constraints of engineering code, more with certain engineering attributes, such as:

  • The same request address can only appear once in the API layer (the number of project interfaces can reduce code redundancy).
  • Do not use more than 100 lines of Hook code (to enhance logic splitting and avoid overly complex logic)
  • Prioritize maintainability when choosing between reusability and maintainability (avoid false encapsulation, coupling a lot of logical judgment in encapsulated code)
  • Business code comment coverage must exceed 10% (to improve code readability and facilitate automated documentation generation)
  • Cross-component communication in the project must be through Redux (reducing the cost of understanding the component value code by the team)
  • It is not allowed to install more than one NPM package with the same functionality (to avoid unnecessary dependency installations and increased maintenance costs).

These business constraints are not the same as ESLint, and different businesses may have different requirements for code, so business constraints require full communication, collision discussion, and firm implementation by developers. Students from different teams may come up with completely different results, but the conclusion of the constraints itself is not important, the important thing is to form a consistent development consensus.

Realize the landing of constraints through mechanism

The constraints themselves are not difficult to formulate, and for the design of the engineering side, it is easier for engineers to form a conclusion after the game through discussion. But landing the mechanics is the harder part. Here are a few enforceable safeguards:

  • CodeView (each CR, in addition to the logical analysis of the business, also needs to be compliance with constraints as a part of the audit)
  • Use a tool to automatically generate parts of the code (e.g. using scaffolding to generate a module in the project code, directives such as ng g component header in Angularcli can help you constrine the structure of the code created by the component).
  • Configure generated code (through configuration, generate logic or form code, establish configuration item standards)
  • Zero code/PaaS platform (generate code through the platform, directly isolate the user from the code, and ensure the quality of the generated code by the platform)
  • Responsible mechanism (constraint landing is directly related to performance and becomes a clear indicator for follow-up)
  • Precipitate documents (through documents, precipitate constraint mechanisms)

Through such mechanisms, the effective implementation of constraints can be ensured, so that the differences in the technical abilities of team members can be erased and a consistent coding style can be formed. While the code under this constraint is not necessarily the most elegant code, at least the engineering quality is not bad. So what constraints actually help us, I think, is to guarantee the lower limit of engineering quality, and then let’s talk about how to raise the upper limit of engineering quality through technological innovation.

Seek innovation on top of constraints

You may have such a question: “will the constraints of the project limit the innovation of technology”. This may be true for small projects with short life cycles, where more explorative breakthroughs with new technologies may result in a larger pool of team skills; However, for large projects, the code design decisions we make every day may affect the development process of tomorrow’s business system. Any technology upgrade must be cautious. At this time, we should not regard constraints as obstacles to innovation, but should regard constraints as a training ground for innovation.

If you’re working on a large project, and you want to push the boundaries, use new technology, and innovate, it means doing the following things:

  1. Have a good understanding of the context of past constraints: the context has not changed and whether new technology can solve the problem solved by the constraints without creating new problems
  2. Ability to articulate the value of the new technology: whether the new technology has a significant impact on performance, stability, experience, R&D efficiency, and business outcomes in terms of consensus building
  3. Be able to present the overall plan for the technology upgrade: when identifying the technology upgrade, did you consider how the historical technical solution could be replaced gracefully
  4. Ability to convince the team to accept new technology upgrades: Can you convince the team to work with you to build on existing technology
  5. Ability to lead a team or deliver a technical solution by yourself: Do you have the ability to deliver new technologies or innovations

In many cases, the technological innovation we make is just the update of the technology stack, which does not bring any value to the team or the business side. However, when we think through these problems and can convincingly prove that the new technology or innovation point is valuable, the upgrade of the system may be the real value.

Innovation in constraints can enable engineers to have more thinking combined with business and produce truly valuable innovations. Such quality thinking and innovation determine the upper limit of engineering quality and cultivate more excellent engineers at the same time.

How to improve the quality of existing projects?

For a large new project, we can design and optimize the architecture in stages in the way described above. But most of the time, we take on projects that we find to be of low quality when we take them on, so how do we improve the code that we already have?

Determine if your system needs improvement

The life cycle of a system can be summarized into three stages:

  • Development period: rapid development of business
  • Stable period: the business situation is stable
  • Recession: business gradually shut down and restarted

For the system in the development period and the system in the stable period, reasonable engineering design will bring obvious benefits in terms of performance and stability in the future. At this time, we can consider to upgrade the technology of the system. For the system in the decline period, although the short-term development and maintenance efficiency is not high, but the development potential of the future system cannot be seen. At this time, it may be a better choice to continue to maintain the old system. Not every system has to be improved. It’s good to keep improving, but it comes down to judging the value of the business.

How to make engineering improvements

Engineering improvement for large projects can be divided into two ways, top-down and bottom-up. For large projects, top-down total refactoring is costly and is not recommended unless you know the system well. On the other hand, mainstream frameworks like React and Vue can host partial DOM, so a bottom-up escalation may be a better strategy. This approach has two advantages: low cost and low risk. For example, we need to upgrade jQuery to React. In this way, we can replace the Backbone code in jQuery layer by layer:

export default View.extend({ componentName: 'AuctionDetailContainer', initialize(options) { const { dataSchemaV1, pageSchema } = options; this.ref = React.createRef(); this.dataSchemaV1 = dataSchemaV1; this.children = pageSchema.getChildren()[0]; this.attributes = pageSchema.getAttributes() || {}; }, render() { ReactDOM.render(( <AuctionDetailContainerWithRef ref={this.ref} taskFields={this.dataSchemaV1} attributes={this.attributes} crossTableData={this.children} /> ), this.$el[0]); return this; }});

In each replacement, we only need to test the logic of the replacement part without affecting other external logic. In this way, the replacement layer by layer achieves a good balance under the two-way requirement of ensuring stability and system upgrade. At the same time, when you take on a new project, this method of upgrading can also help you to gradually clarify the logic of the business and understand the business.

In such a step-by-step replacement process, combined with the coding constraints mentioned above, we can gradually improve the code quality of the system. Then, through innovation, the project can be further optimized and perfected to complete the entire refactoring process.

In this process, there are some tools that can also help us, a few examples:

  • Commintlint + Semver Semantic version number control specifications: Helping teams understand the risks associated with refactoring and saving communication costs
  • Front-end automated testing tools: ensure project quality through unit testing and reduce the probability of regression error
  • Chrome Coverage: A tool that helps you find useless code and streamline your project logic

conclusion

The specific coding content involved in this paper is not much, I hope it can give you some inspiration and thinking from another aspect of engineering test, some conflicts of views are also welcome to communicate and discuss.

The article may be reprinted freely, but please keep the link to the original article.


Passionate you are welcome to join us
ES2049 Studio, please send your resume to [email protected].