This article follows from the author’s annual summary of last year: 2015- My Front-end Road: Data Flow Driven Interface. In addition, if you are interested in the overall programming technology system and thinking, I recommend reading another review article: 2016- My Technical Path: Programming Knowledge Architecture Diagram.

preface

Twenty glorious years




In recent years, with the improvement of browser performance and the surging tide of mobile Internet, Web front-end development has entered the era of rapid progress. It’s the best of times, we’re always moving forward, and it’s the worst of times, with countless front-end frameworks and technology systems competing to leave developers confused and even at a loss what to do. Web front-end development can be traced back to the 1991 Tim Berners-Lee publicly mentioned HTML description, and then in 1999 W3C released HTML4 standard, this stage is mainly BS architecture, there is no so-called front-end development concept, Web page is just a back-end engineer’s work, server side rendering is the main way of data transfer. In the following years, with the development of the Internet and the proposal of architectural standards such as REST, the concept of front and back end separation and rich client became increasingly recognized. We needed to expand the language and basic API. At this stage, a series of front-end auxiliary tools represented by jQuery emerged. Since 2009, with the popularization of smart phone development and the overwhelming trend of mobile terminal, the design concept of SPA single-page application has also become popular, and the related front-end modularization, componentization, responsive development, hybrid development and other technologies are urgently needed. This stage has spawned a series of excellent frameworks such as Angular 1 and Ionic, as well as module standards and loading tools such as AMD, CMD, UMD and RequireJS and SeaJS. Front-end engineers have also become specialized development areas, with technical systems and architectural patterns independent of back-end. In the past two years, with the improvement of Web application complexity, the expansion of team members, users’ demand for friendly page interaction and performance optimization, we need a more excellent and flexible development framework to help us better complete front-end development. At this stage, many frameworks with relatively concentrated concerns and better design concepts emerged, such as React, VueJS, Angular 2 and other component frameworks that allow us to replace DOM operations with declarative programming, which speeds up the development of components and enhances the reusability and composability of components. Redux, which follows functional programming, and MobX, which draws on the concept of responsive programming, are both very good auxiliary frameworks for state management, helping developers to separate business logic from view rendering, divide project structure more reasonably, implement the principle of single responsibility better and improve the maintainability of code. In terms of project construction tools, task operation management represented by Grunt and Gulp and project packaging tools represented by Webpack, Rollup and JSPM are leading the pack respectively, helping developers build a better front-end construction process and automate pre-processing, asynchronous loading, Polyfill and compression. Dependency management tools, such as NPM/Yarn, have always ensured the convenience of code publishing and sharing, laying an important foundation for the prosperity of the front-end community.

The disruption of the rainbow

I saw a tweet from Thomas Fuchs the other day that sparked a heated discussion in Reddit and other communities: We spent 15 years splitting HTML, JS, and CSS, and suddenly things seem to have come full circle.



The division of each module in front-end development or the so-called separation of front and back ends cannot be formalized simply according to language or module, or it needs to give consideration to functions and reasonable division. The author in2015- My Way to the front end: Data Flow-driven interfacesAs mentioned in the summary of his front-end experience in 2015, any programming ecosystem will go through three stages. The first stage is the primitive stage, which will give rise to a large number of Tools due to the need to expand on the language and basic API. The second stage, as things get more complicated and need more organization, introduces a lot of design patterns, the concept of architectural patterns, and this stage leads to a lot of Frameworks. In the third stage, with the further complexity of requirements and expansion of the team, it entered the engineering stage, including various layered MVC, MVP, MVVM, visual development, automated testing, and team collaboration system. At this stage, lots of small and beautiful libraries emerge. During the first half of 2016, I struggled with the React stack and tried VueJS and Other good front-end frameworks like Angular. I was tired of the instrumental transformation from an imperative development model that operated directly on DOM nodes to a state/data flow-centric development model. In the second half of 2016, the authors reflect on whether it is necessary to use the React/story/Webpack/VueJS/presents, whether it is necessary to constantly chase of a Benchmark record new framework? The title of this paper is instrumentalization and engineering, which represents the main idea of this paper. We hope to break away from tools as much as possible and return to front-end engineering itself and language itself. React, AngularJS and VueJS are more about assisting development and selecting appropriate tools for different projects. Rather than obsessing over the tool itself.

In summary, front-end instrumentalization has entered a very prosperous era, with many front-end developers struggling to learn. Tools will change very quickly, and many excellent tools may be just waves in the long history, while the engineering thinking contained in them will last forever. Whether you’re using React or Vue or Angular 2 or some other great framework, it shouldn’t stop you from trying something else. Learning Vue helped me understand React and modern Web framework design. Also for their own in the future work more free and flexible choice of scaffolding according to local conditions to broaden the vision.

At the end of the introduction, I’d like to mention one word that I’ve seen most frequently in the front end this year: Tradeoff.

tools




The moon waxes and wanes. I believe many people have read the article about how to experience the front-end in 2016. The front-end in 2016 really makes people feel that from entry to give up, the speed of our learning has not kept pace with the emergence of new frameworks and new concepts, and the cost for learning is far greater than the cost of actual development projects. I welcome the instrumentalization trend. We don’t have to use the latest and greatest tools, but the fact that we have more options is good news for most non-Virgos. At the end of the year, there is also a cao Liuyang: 2016 front-end technology observation has also triggered a hot discussion among everyone. To be honest, the author personally agrees with the opinion of the article half to half, neither blowing nor black. But the author saw this article’s first feeling when the author must be a big company. The consideration of technology selection caused by technical liabilities and the relatively complete manpower to carry out a project mentioned in this paper are often characteristics that small and medium-sized start-up companies do not have.

Meaning of instrumentalization

Instrumentalization makes sense. I strongly agree with The Vue 2.0 concept of progressive front-end solutions. Tools exist to help us deal with complexity, and the abstract problem we face when selecting technologies is the complexity of the application versus the complexity of the tools used. Tool complexity can be understood as an investment in dealing with the inherent complexity of the problem. Why is it called investment? That’s because if you invest too little, you don’t get scale, you don’t get a reasonable return. It’s like when a startup takes venture capital, how much is important. If the problem you’re trying to solve is complex, and you tackle it with a tool that’s too crude, you run into a problem where the tool is too weak to be productive. Is on the contrary, if want to solve the problem is not complicated, but you use very complex framework, then it is equivalent to kill on the wheel, will encounter tool complexity caused by side effects, not only will lose the advantage brought by the tool itself, also increases the various problems, such as training costs, loop, and the actual development efficiency, etc.




Decade of GUI application architecture, that change: MVC and MVP, MVVM, Unidirectional, Clean the article talk about the so-called GUI application architecture, is for the rich client code organization/responsibilities. In a survey of the changes in Architecture patterns over the past decade, it can be divided into two categories, MV* and Unidirectional, while Clean Architecture takes a unique approach with strict hierarchical division. From the author’s perspective, the transition from MVC to MVP completes the decoupling of View and Model, and improves responsibility allocation and testability. From MVP to MVVM, data binding between View and ViewModel is added, making View completely stateless. Finally, the switch from MV* to Unidirectional uses a message-queue data-flow driven architecture, and Redux switches the fragmented state management from MV* to Unidirectional, ensuring the order and traceability of states. In terms of front-end evolution, Angular 1 actually started to shift from directly manipulating Dom nodes to state/data flow centric. JQuery represents the traditional DOM-centric development model. However, the React/state-centric development model is now popular for complex page development. When the application is complex, manipulating the DOM directly means maintaining the state manually, and when the state is complex, it becomes uncontrollable. React is state-centric and automatically renders the DOM for us, while maintaining performance through efficient DOM Diff algorithms.

Defects of instrumentalization: Abstraction vulnerability theorem

Abstract vulnerability theorem was proposed by Joel in 2002. All self-evident abstractions have vulnerabilities. Abstract leakage refers to any abstraction that tries to reduce or hide complexity. It does not completely shield details. Complex details that try to be hidden are always likely to leak out. Abstract vulnerability law states: any time an abstraction tool can improve efficiency, although it saves our working time, but it can not save our learning time. We have discussed in the previous chapter that the introduction of instrumentalization actually eliminates intrinsic complexity at the cost of bearing the complexity of the tool, and the result of instrumentalization abuse is the imbalance between the complexity of the tool and intrinsic complexity.

At this point, it becomes clear that different projects have different intrinsic complexity, that a one-size-fits-all approach to evaluating the quality and usefulness of tools is a rogue, and that the quality of the project developer, customer, or product manager can have an impact on the intrinsic complexity of a project. For typical small active pages, such as a wechat H5 propaganda page, often focus on interactive animation and loading speed, logic complexity is relatively low, at this time, Vue such a gradual low complexity library will show its strength. However, for complex Web applications, especially those that need to consider multi-end adaptation, the author tends to use a relatively strict library like React.

The React? Vue? Presents 2?




I’ve been translating a couple of reviews lately, and it’s interesting to note that if you don’t mention or praise Vue, you get a bunch of reviews: junk, and if you don’t mention or praise Angular 2, you get a bunch of reviews: junk. I guess if I didn’t even mention React, it would be a bunch of comments: garbage. Well, although it may be that the author’s translation is indeed bad and has tainted the original text, the author feels that this kind of anger is a lack of respect for technology. React, Vue, and Angular 2 are all excellent libraries and frameworks that have their own advantages in different application scenarios. This chapter is a brief elaboration of my point of view. Vue’s greatest strength is its incremental thinking and friendlier learning curve. Angular 2’s greatest strength is its compatibility with a complete out-of-the-box all-In-one framework. In some cases, these two strengths are also its weaknesses, which are why some people choose React. The author thinks that a lot of disputes and even invective about the technology selection are not necessarily the problem of the tool, but the tool users can not correctly understand themselves or think about the application scenarios of others, and ultimately the quarrel is wrong.

Small and beautiful view layer

React and VueJS are both small and beautiful view-layer libraries, not compatible Frameworks like Angular 2. Any programming ecosystem goes through three phases. The first is the primitive phase, where the need to expand on the language and underlying apis leads to the proliferation of Tools. The second stage, as things get more complicated and need more organization, introduces a lot of design patterns, the concept of architectural patterns, and this stage leads to a lot of Frameworks. In the third stage, with the further complexity of requirements and expansion of the team, it entered the engineering stage, including various layered MVC, MVP, MVVM, visual development, automated testing, and team collaboration system. At this stage, lots of small and beautiful libraries emerge. React does not provide a lot of complex concepts and complex apis. Instead, it focuses on providing clear, concise and abstract view-layer solutions, and provides flexible extension solutions for complex application scenarios. For example, MobX/Redux state management tools are introduced according to different application requirements. React is superior in terms of scalability, the completeness of the basic knowledge required for advanced research and learning, and the testability of the entire application hierarchy. React has a steep learning curve and a high threshold to get started. In particular, the introduction of JSX and a large number of ES6 syntax makes many front-end developers who are used to jQuery syntax feel that the learning cost may be greater than the development cost. Vue, on the other hand, is a typical so-called progressive library, that is, you can gradually introduce various dependencies on demand and learn relevant syntax knowledge. The intuitive feeling is that we can download the Vue library directly from the CDN at the beginning of the project, insert it into THE HTML using familiar scripting methods, and then render the data directly using Vue in script tags. Over time and as project complexity increases, routing, state management, HTTP request abstraction, and, eventually, overall packaging tools can be introduced. This incremental nature allows for the freedom to match different solutions depending on the complexity of the project, such as the speed of development and high performance benefits of using Vue in a typical active page. However, this kind of freedom also has pros and cons. The so-called “sharpening the knife without cutting the material by mistake”, React’s relatively strict specification makes a good addition to the unified code style and code quality guarantee within the team. In short, I personally feel that Vue will be more acceptable to pure front-end developers because it will be less costly to switch from HTML layout and jQuery to directive support for two-way data binding. In particular, there will be less need to modify existing code bases and lower refactoring costs. React and its relatively strict specifications may be easier for back-end developers to accept. They may be confused by a lot of concepts when they first learn React, but the strict component classes and the operation of member variables/methods will be more comfortable once they become familiar with React. As Dan Abramov explained, Facebook launched React as a way to ensure component consistency and reusability in the ongoing iterations of their hundreds of cross-platform sub-products.

Functional thinking: abstract and intuitive

In recent years, with the increasing complexity of application business logic and the large-scale application of concurrent programming, functional programming is in the foreground. There is a saying in software development that mutable state is the root of all evil, and functional programming avoids some of the common pain points of object-oriented programming by avoiding the use of shared state. To be honest, I don’t want to be a fan of functional programming. In my discussion of Redux and MobX, I will also mention that functional programming inevitably leads to fragmentation of business logic, which in turn reduces overall code maintainability and development efficiency. In contrast to React, Vue is a very straightforward code architecture. Each Vue component contains a Script tag, where we can explicitly declare dependencies, declare methods for manipulating data, and define properties inherited from other components. Each component also contains a template tag, which is equivalent to the Render function in React, to bind data directly as properties. Finally, each component includes a style tag to ensure direct isolation of component styles. Take a look at a typical Vue component. It’s very straightforward, and the comparison will help you understand the React design idea.

<script> export default { components: {}, data() { return { notes: [], }; }, created() { this.fetchNotes(); }, methods: { addNote(title, body, createdAt, flagged) { return database('notes').insert({ title, body, created_at: createdAt, flagged }); }}; </script> <template> <div class="app"> <header-menu :addNote='addNote' > </div> </template> <style scoped> .app { width: 100%; height: 100%; postion: relative; } </style>Copy the code

When we turn our perspective back to React, the component that acts as a one-way data binding can be abstracted into the following render function:

View = f(Data)
Copy the code

This is a refreshing way to abstract the user interface, so that the combination and collocation of the interface can be abstracted into a combination of functions, a complex interface can deconstruct the combination and transformation of several different function calls. In version 0.14, React abandoned MixIn in favor of higher-order function patterns for component composition. A big consideration here is that mixins are object-oriented programming, an implementation of multiple inheritance, while Composition in functional programming can serve the same purpose and ensure component purity without side effects.

The JSX syntax looks weird to many people when they first learn React. Does this departure from traditional HTML template development really make sense? Vue also introduced JSX syntax support in version 2.0. JSX isn’t just a traditional HTML template. JSX is essentially an abstraction of the React. CreateElement function, which maps objects in plain JavaScript to a DOM representation. The general idea is as follows:




In modern browsers, JavaScript can be computed much faster than DOM manipulation, especially when redrawing and rerendering are involved. In addition, JavaScript objects are used to replace DOM, which is strongly related to the platform, to ensure the support of multiple platforms. For example, with the assistance of ReactNative, we can easily run a set of code on iOS, Android and other platforms. In summary, JSX is still JavaScript at heart, so we retain the advantages of JavaScript functions in composition, syntax checking, and debugging while still getting the convenience and readability of declarative HTML usage.

Front and back end separation and full stack: Technology and people




Front and back end separation and full stack is not a new term, have led the fashion for a while. Five years ago, when I first came into contact with the concept of front and back end separation and the definition of full-stack engineer, I was enlightened. At that time, I also intended to become an excellent full-stack engineer. However, now I think that the title was more for me to know a little about everything but not to master it. Run into a little deeper point of the problem at a loss for their own psychological comfort. The separation of the front and back ends of the Web has significant advantages, which plays a great role in the development speed and reliability of the whole product. Full stack engineer is of great significance to the improvement of programmers themselves, and has a certain increase in the initial speed of the project. If the division is reasonable, it can promote the overall development speed and reliability of the whole project, but if the division is not reasonable, it will only lead to the project interface chaos, a mess. However, the two concepts seem to conflict slightly, and what we often say about the front and back end separation involves the following two levels:

  • The data rendering work that was originally the responsibility of the server is handed over to the front-end, and the front-end and the server can only communicate with each other through a standardized protocol.

  • Organizational separation, from early server-side developers writing an interface to a full front-end team building an engineered front-end architecture.

The front and back end separation is essentially the front and back end for different technology selection and project architecture, but many of the two ideas can also be integrated, such as responsive programming or functional programming and other ideas are reflected in the front and back end. However, the whole stack seems to return to the state of splitting according to requirements in terms of both technology and organizational structure. However, we must face the reality that most engineers are not able to achieve full stack, which is not specific code technology, but the understanding of the front-end and back-end, and the understanding of the business logic of the system. If we assign to a complete business block, at the same time, we end up with an infinite number of fragmented and independent systems.

Complementary client-side rendering and server-side rendering

  • Tradeoffs in Server side and client side rendering Dr. Roy Thomas Fielding’s Architectural Styles and the Design of Network-based Software Architectures

The author mentioned in 2015- My Front-end Road that the initial web page is a mixture of data, templates and styles, that is, taking the classic APS.NET, PHP and JSP as examples, the template on the server side provides a series of tags to complete the flow from business logic code to the page. So, the front end is just for displaying data, the so-called vassal. With the popularity of Ajax technology, WebAPP is also regarded as CS architecture. Abstractly speaking, CS is the two-way communication between client and server, while BS is the one-way communication between client and server. In other words, the web itself becomes stateful. From the initial opening of the page to the final closing, the page itself also has a set of state, and the basis of having this changing state is AJAX, that is, from one-way communication to two-way communication. The illustration is as follows:




This is how the idea of separating the front and back ends developed, but in the last two years the concept of server-side rendering has come back to the fore with the popularity of React. It should be emphasized that the technology we now call server-side rendering is not the traditional server-side template data filling represented by JSP and PHP. A more accurate description of server-side rendering is the pre-start and pre-load of the client application. We are not trying to bring the client code back to the server to run in order to replace the existing API server, and the code that has been run on the server also needs to be run again on the client. Describes the transition from pure client-side rendering to server-side rendering in a progression of three levels. The advantages of introducing server-side rendering lie in the following three areas:

  • Modern Web frameworks such as React, Angular and Vue have abandoned their support for older browsers. After the introduction of server-side rendering, users with older browsers can at least be provided with a more user-friendly first screen display, although the subsequent functions are still unavailable.

  • More search engine friendly, client-side rendering means that the entire rendering is scripted, which is not crawler friendly. Although modern crawlers often support script execution through built-in automatic browsers and other means, but this will increase the load of many crawler servers, so large search engines like Google still rely on the document itself when indexing web pages. If you want to improve your search engine rankings and make your site more easily searchable, supporting server-side rendering is a good choice.

  • Overall loading speed and user experience optimization, in the first screen rendering, the performance of server rendering is much faster than that of client rendering. However, due to the limitation of network bandwidth and re-rendering, server-side rendering will be weaker than client-side rendering in subsequent page response update and sub-view rendering. In addition, at the same time of rendering on the server side, we will also grab part of the application data on the server side and attach it to the document. Under the current situation that HTTP/1.1 is still the mainstream, the connection number and delay of the client request can be reduced, so that users can access the required application data more quickly.

In summary, server-side rendering and client-side rendering complement each other, and with the help of frameworks like React, we can easily add server-side rendering support to development-stage pure client-side rendering applications.

Full stack engineer in project: technology full stack, demand isolation, rational allocation

  • full-stack-between-reality-and-wishful-thinking

  • Why do you need to be a full stack developer?

Full-stack engineer is of great significance for personal development, and it is of great positive significance for actual project development, especially for projects in small and medium-sized start-up companies where progress is the first baton. But the full stack often means a certain Tradeoff, the pace is too big, easy to pull the egg. It is best not to make any technical architecture and process adjustments that violate Conway’s law, which states that the organization of design systems produces design equivalent to the structure of communication within and between organizations. This is the first time that the author mentioned Conway’s law in this paper. In practice, the author found that some results of full stack are forced to assign tasks according to functions, that is, in the simplest case, login and registration may be assigned to one person or a group from database design, server interface to front-end interface. Then the concrete implementer, who is generally responsible for all the logic from top to bottom, ignores the necessary specification in many areas that should be normalized, especially in interface definitions, for the sake of speed. As a result, the entire system is fragmented into one island after another, with variable names that express the same meaning between different functional blocks colliding, and a dizzying array of bizarre ids, Uuid, {resource}_id.

At the end of this year, many technical exchange platforms started denounce full-stack engineers. Taking the discussion of why full-stack engineers cheat on Zhihu as an example, people’s black points about full-stack engineers mainly lie in:

  • Leon-ready: Full stack engineers are getting harder to exist, many of them just make up the number. With the development of the Internet, in order to deal with different challenges, different directions need to spend a lot of time and energy to solve problems, job segmentation is inevitable. For so many years, the accumulation of expert experience and skills in each direction is not for nothing, people’s energy and time are limited, the more development in the future, the more chance to appear in the real sense of the full stack.

  • Wheel brother: it’s ok for a person to pursue full stack, that’s his personal freedom. But if a job goes for the full stack and then advocates it, it’s a sign that the company is unhealthy and inefficient.

An important feature of modern economic development is the increasingly precise division of labor in society. It is impossible to become a omniscient generalist. However, in the above criticism, we can also see that full stack engineer is very meaningful for personal development. It is the stone of other mountains that can attack jade. The author advocates job rotation in my small team. After the completion of a project cycle, part of the front and back end engineers will be replaced, on the one hand, in order to avoid the complex and transactional development that makes everyone too tired. On the other hand, it is also hoped that everyone can understand each other’s work, so that when bugs occur in the future, they can put themselves in others’ shoes. After all, contradictions within the team, especially among different groups, have always been a headache in project management.




engineering

I am a little tired of writing here intermittently. This part should be the most important chapter, but I will be killed if I don’t write my graduation thesis. T, T, I will supplement and improve it in the future article.




What is engineering

The so-called engineering is the technical framework and project organization for a product demand, and the fundamental goal of engineering is to achieve reliable products as quickly as possible. The shortest possible time includes speed of development, speed of deployment, and speed of refactoring, while reliability lies in testability, variability, and Bug reoccurrence and location.

  • Development speed: development speed is the most intuitive and obvious engineering measurement index, and also the core contradiction between other departments and programmers. Most outstanding engineering solutions first is the speed of development, but the author has also stressed that the sentence, a knife and cut materials, we are looking for the fastest local can’t ignore the overall optimal at the same time, the early simple pursuit of the speed of technical debt will cause irreparable damage for later stages.

  • Deployment speed: One of the most common things I say to a test or product manager in my daily work is that I’ve changed it locally but haven’t pushed it online yet. In today’s world of DevOps and CI tools, automated compilation and deployment saves us a lot of trouble. Still deployment speed is an important measure of cannot be ignored, especially by NPM elusive package management tools and don’t know when will take a wind server will compile the deployment process caused great threat to our, often depend on the number of project increase, the structure of chaos will also increase the speed of deployment is not controllable.

  • Reconstruction speed: Listen to the product manager say that our demand will change again, listen to the technical Leader say that a new technology stack has been released recently, which is far away from the present.

  • Testability: Many teams now advocate test-driven development, which is important for improving code quality. The choice of engineering scheme also has a great impact on the testability of the code. There may be no code that cannot be tested, but we should try to reduce the test cost of the code and encourage programmers to be more active in writing test code.

  • Variability: Programmers say: This requirement can’t be changed!

  • Bug reappearance and location: there is no program without bugs, especially in the initial requirements are not clear, the emergence of bugs is inevitable and unavoidable, excellent engineering scheme should consider how to assist programmers to locate bugs more quickly.

Whether it is front end separation, back end popular MicroService or front end MicroFrontend, its core is to sacrifice local development speed for faster global development speed and improved system reliability. The difference between an entry-level programmer and an intermediate programmer may be that the former only know how to do it, but they don’t know why, and their only metric is speed of development, speed of feature implementation, amount of code, etc. Intermediate programmers, on the other hand, can take into account both the development speed and the quality of the code within their scope of responsibility. They will constantly Review and merge and divide the code in the development process, so as to achieve as little code as possible on the basis of adhering to the SRP principle. On the other hand, the difference between pure Coder and TeamLeader lies in that the former pays more attention to local optimization, which may refer to a specific module in the front and back end of the project, or the latest development goal in the time dimension. However, a TeamLeader needs to plan strategically and make overall plans. Not only do you need to complete the tasks delivered by your boss, but you also need to reserve interfaces for possible iterations on the product or lay the foundation for scalability in advance. To sum up, when we explore the concrete implementation scheme of engineering, in terms of technical architecture, we will focus on:

  • Modularization of functions and componentization of interfaces

  • A unified development specification and code style enables the required functionality to be achieved with minimal code while following the SRP single responsibility principle, ensuring a reasonable separation of concerns.

  • Testability of code

  • Easy to share code base and dependency management tools

  • Continuous integration and deployment

  • Project online quality assurance

Engineering requirements for the front end

When we landed at the front end, the author felt the following outstanding problems in the past years of practice:

  • Front and back end business logic connection: In the case of separation of front and back end, the front and back end is each system and team, so the communication between the front and back end has become one of the main contradictions in project development. The front-end is often divided into modules and named variables according to the interface during development, while the back-end is used to dividing modules according to abstract business logic and naming variables according to the database definition. The simplest but most common problems are that they may have different names for variables with the same meaning, and that the back-end interface can change frequently given the changing business requirements. At this point, it is necessary for the front end to set up a special interface layer pair to shield such changes and ensure the stability of the interface layer.

  • Reuse of components from multiple business systems: When we are faced with new development requirements or have multiple business systems, we want to reuse existing code as much as possible, not only to improve development efficiency, but also to ensure consistency of application style within the company.

  • Multi-platform adaptation and code reuse: In the face of the trend of mobile, our applications need to consider not only PC support, but also wechat mini program, wechat H5, WAP, ReactNative, Weex, Cordova and other platforms. Here we want to be able to try to reuse code to ensure the speed of development and reconstruction speed, there is need to emphasize that the author think mobile terminal and the PC itself is different design style, the author disagrees with too much considering the response of the so-called type development reuse component interface, more should be focus on logic code reuse, though this would inevitably affect efficiency. You can’t have your cake and eat it too, which needs to be adapted to local conditions and can’t be generalized.

Summarized to specific technical points, we can draw the following derivation diagram:




Declarative rendering or variable imperative operations are needed in any situation, from DOM manipulation centric to data flow driven to minimize redundant code and improve development efficiency. Here I would like to compare jQuery with Angular 1:

var options = $("#options");
$.each(result, function() {
    options.append($("<option />").val(this.id).text(this.name));
});
<div ng-repeat="item in items" ng-click="select(item)">{{item.name}}
</div>
Copy the code

React, Vue, Angular 2 and their extensions all provide support for es6-based declarative components. On top of basic declarative components, we need to build reusable and composable component systems. Usually, a component system is composed of empty units that are segmented from the large interface of one of our applications. This is the section on the deconstruction design draft of the front-end architecture below. When we have large component systems, or a lot of components, we need to think about jumping between components. Especially for single-page applications, we need to map the URL to the state of the application, which in turn determines the currently displayed components. What do we do at the application of the increasingly complex, when the application is simple, may be a very basic state and interface mapping can solve the problem, but when the application becomes large, involving collaboration, will involve the Shared among multiple components, multiple components need to change the same state, and how to apply this scale can still run efficiently, There’s the issue of large-scale state management, and of course maintainability, and build tools. Now, if you look ahead to the future, when HTTP2 becomes ubiquitous, it could lead to a revolution in building tools. But for now, especially in China’s online environment, packaging and engineering remains a very important and inevitable part of the process. Finally, from the perspective of front end projects, they can be divided into the following categories:

  • Large Web applications: Service functions are extremely complex. With MVVM frameworks such as Vue, React and Angular, more and more components are bound to be used in the development process. Communication between parent and child components and communication frequency between sub-components will greatly increase. Managing the flow of data between these components is the biggest challenge for such WebApps.

  • Hybrid Web APP: The conflict lies in performance and user authentication, etc.

  • Activities page

  • The game

MicroFrontend: the MicroFrontend

  • Micro Frontends

There is no doubt that microservices bring convenience to the construction of scalable and maintainable large-scale service clusters, and now with the increasing complexity of front-end applications, so-called megalithic front-end applications are emerging in an endless stream. Large, bulky Web applications can be just as difficult to maintain as server-side applications, so ThoughtWorks introduced the concept of a MicroFrontend this year. The core concepts of microfront-end and microservices are the same. Huge Web applications are segmented by pages and functions, and different teams are responsible for different parts. Each team can apply related technologies to develop related parts according to their own technical preferences, where BFF-backend for frontends tends to be useful.

A realistic front-end development plan

The last part of this article looks at the front-end development plan that I have worked out in practice over the past year. Why is it a back-to-reality front-end development plan? This is because the biggest problems I feel I have encountered are unclear requirements, unstable interfaces and uneven quality of developers. Regardless of the technical aspect, the organizational aspect of the project development is that we want to get the most out of everyone involved, regardless of their level. Everyone can write components, everyone can write entity classes, but they don’t necessarily write the right quality code. On the other hand, good architectures are derived from different industry fields, application scenarios, and interface interaction requirements. We need to keep an open mind and keep extracting common code at the right level of reuse. At the same time, avoid the problems of excessive abstraction. The reasonable team collocation method advocated by the author is as follows, which is more for small companies with insufficient manpower, one should be used as two, I wish all the staff are full stack:




Declarative programming versus data flow driven: Some gains and some losses

  • Think: What front-end state management tools do I need?

Redux is a full-on practitioner of functional programming (if you don’t already understand Redux, check out my In-depth Understanding of Redux:10 Redux Practice Tips from experts), Its core technology focuses on a Reducer following Pure Function and a Single State Tree following Immutable Object, providing Extreme Predictability and Extreme Testability. Correspondingly, a large number of Boilerplates are required. MobX is Less Opinioned, born out of Reactive Programming, The core idea is that Anything that can be derived from the application state, should be derived. Automatically, you can avoid any repeated state. Redux uses Uniform Single State Tree, while the author who is used to Object Oriented Programming in back-end development can not help but also want to introduce Entity in the front end, or in terms of design ideas. For example, for the increase, deletion, change and check of TodoList, the author hopes to include it in a Certain TodoList object without splitting all operations into three parts, Creator, Reducer and Selector. I just want to show a simple list. The first class I learned in college was OOP, and I have been deeply influenced and instilled with OOP ideas in C#, Java, Python, PHP and many other back-end fields. Mutable state is undeniably the root of all evil in software engineering, but OOP’s description of business logic and its guarantee of readability and understandability of code organization is better than declarative, slightly abstract FP. I accept the idea of functional programming as an integral part of a project’s building organization, but should programming ideas come first and business requirements later at any stage of any project? This is certainly a bit of politically correct hooliganism. Typical situations Dan recommends for Redux are:

  • Easily store application state locally and read recovery state on reboot

  • It is easy to set up the initial state on the server side and render the state on the server side

  • Can serialize record user actions, can set up status snapshots, so as to facilitate Bug reporting and developer error recurrence

  • The ability to pass user actions or events to other environments without modifying existing code

  • Ability to add weight or undo functionality without refactoring code

  • The ability to trace state history during development or to reproduce state from Action history

  • It provides developers with a comprehensive and thorough interface to review and modify existing development tools, enabling product developers to tailor tools to their own application needs

  • The ability to construct different interfaces on the basis of reusing most of today’s business logic

Progressive state management

  • redux-mobx-confusion

Do different things at different times, when we’re writing pure components, we need to explicitly declare all the state/data, whereas for actions we can put in Store deferred Action. For simple forms, for example, we initially encapsulated all the logic of data entry, validation, submission, and result feedback within the form component. Then, as component complexity increases, we need to shard the code for different functions, and we can create a dedicated Store to handle the state and logic of the form. Abstractly, the state management we need at different stages corresponds to:

  • Prototype: Local State

At this stage we might place the data fetching functions directly into componentDidMount, and store both UI State and Domain State in LocalState using setState functions. This approach is the most efficient, with the least amount of code, but it is less scalable and less conducive to sharing state between views.

// component
<button onClick={() => store.users.push(user)} />
Copy the code

Store here refers only to pure data stores or model classes.

  • Project growth: External State

As projects become more complex, we need to look for specialized state management tools to manage external state:

// component
<button onClick={() => store.addUser(user)} />

// store
@action addUser = (user) => {
  this.users.push(user);
}
Copy the code

You can also change the state directly inside the component at this point, using the same code style as in phase 1 and manipulating the store object directly, but you can also avoid this bad practice by introducing Strict mode:

// root file
import { useStrict } from 'mobx';

useStrict(true);
Copy the code
  • Multi-person collaboration/strict specification/complex interaction: Redux

As the size of the project increases and the number of participants increases, it is best practice to use declarative Actions and it is time for Redux to shine. At this point, Redux’s biggest limitation is To Use Explicit Actions To Change The State without directly changing The application State.

// reducer
(state, action) => newState
Copy the code

Progressive front-end architecture

The front-end architecture in the author’s mind is as follows, which is explained according to the process of the project and the modules that should be developed at different development times:




Deconstructed design draft




Pure component

After deconstructing the design draft, we need to summarize the pure components, at this point the so-called StoryBook Driven Development comes into play, for example, the author summarizes the Material UI Extension, a common class library.

Entity class

Entity class is actually a statically typed language, which can unify data specifications from an engineering point of view. The author mentioned Conway’s Law above, that the design generated by the organization of the design system is equivalent to the communication structure within and between the organizations. Entity classes, coupled with static type-checking tools like TypeScript and Flow, make it easy for the IDE to hint at syntax and avoid static syntax errors as much as possible. At the same time, when business requirements change and we need to reorganize parts of the business logic, such as changing some key variable names, the changes can be made more easily and securely through a unified entity class. At the same time, we also need to place part of the logic into the entity class, such as the typical mapping between the state code and its description text, calculation of some static variable values, etc. :

Models: [ModelEntity] = []; cover: string = ''; If (this.models && this.models. Length > 0 &&) if (this.models && this.models. Length > 0 &&) if (this.models && this.models this.models[0].image) { return this.models[0].image; } return 'https://coding.net/u/hoteam/p/Cache/git/raw/master/2016/10/3/demo.png'; }Copy the code

In the entity base class, we can also define some common methods:

/** * @function Export default class EntityBase {// Entity class name: string = 'defaultName'; / / the default constructor, add data to the current class constructor (data, self) {/ / determine whether incoming self, if is empty, the default value for the current self = self | | this; } // Filter value null for attribute ''. {const newObj = {}; for (let key in this) { if (this.hasOwnProperty(key) && this[key] ! == null && this[key] ! == void 0 && this[key] ! == '') { newObj[key] = this[key]; } } return newObj; } @assignProperties (data = {}) {let properties = object.keys (this); for (let key in data) { if (properties.indexOf(key) > -1) { this[[key]] = data[[key]]; }} /** * @function * @param data */ parseDateProperty(data) {if (! Data) {return} created_at, updated_at if (data.created_at) {if (data.created_at.date) {data.created_at.date = parseStringToDate(data.created_at.date); } else { data.created_at = parseStringToDate(data.created_at); } } if (data.updated_at) { if (data.updated_at.date) { data.updated_at.date = parseStringToDate(data.updated_at.date) } else { data.updated_at = parseStringToDate(data.updated_at); } } if (data.completed_at) { if (data.completed_at.date) { data.completed_at.date = parseStringToDate(data.completed_at.date); } else { data.completed_at = parseStringToDate(data.completed_at); } } if (data.expiration_at) { if (data.expiration_at.date) { data.expiration_at.date = parseStringToDate(data.expiration_at.date); } else { data.expiration_at = parseStringToDate(data.expiration_at); ToString () {return json.stringify (object.keys (this)); } /** * @function generate random number * @return {string} * @private */ _randomNumber() {let result = "; for (let i = 0; i < 6; i++) { result += Math.floor(Math.random() * 10); } return result; }}Copy the code

interface

The interface is mainly responsible for data acquisition, while the interface layer has a responsibility is to shield the upper layer server interface details, interface assembly and merging. The author mainly uses Fluent Fetcher summarized, for example, we want to define the most common login interface:

/** * Log in to the param account using an email or mobile phone number * @param password Password * @returns {UserEntity} */ async loginByAccount({account,password}){ let result = await this.post('/login',{ account, password }); return { user: new UserEntity(result.user), token: result.token }; }Copy the code

It is recommended that developers directly test the interface after it is written:

let accountAPI = new AccountAPI(testUserToken);

accountAPI.loginByAccount({account:'[email protected]',password:'1234567'}).then((data) => {
  console.log(data);
});
Copy the code

You can run it directly using Babel-Node, and professional testers can write more complex specs.

Container/high-level component

Containers are often used to connect state management and pure components. I like THE LiveTemplating feature of IDE. Typical container templates are:

// @flow import React, { Component, PropTypes } from 'react'; import { push } from 'react-router-redux'; import { connect } from 'react-redux'; */ @connect(null, {pushState: push, }) export default class ContainerName extends Component { static propTypes = {}; static defaultProps = {}; /** * @function default constructor */ constructor(props) {super(props); Render () {return <section className="">  </section> } }Copy the code

Server side rendering and routing

For server rendering and routing, see Webpack2-react-redux-Boilerplate.

Online quality assurance: front end is difficult, not front end

Just because front-end development is done doesn’t mean everything is done, I wrote in a weekly paper that the bugs we currently call bugs fall into three categories: (1) Bugs caused by developer carelessness: This type of Bug is inevitable, but highly controllable, and the front-end is currently configured with specialized auxiliary unit testers, this type of Bug at most in the early stage of development, and will gradually reduce with the improvement of the project. (2) Bugs caused by demand changes: This type of Bug is inevitable and controllable. However, it has little impact on the formal environment and affects the personal emotions of programmers at most. (3) Bugs caused by interface changes: This type of Bug is inevitable and has high theoretical controllability. Among the bugs fixed last week, this type of Bug accounts for the largest proportion. It is suggested that the Release or MileStone should be assigned according to the version when the back-end is released in the future, and a certain grayscale replacement period should be set after the official launch, that is, the compatibility of both versions should be maintained for at least a period of time.

Online quality assurance is often faced with many uncontrollable factors, such as failure to send registered emails due to overdue email service fees. The author established Frontend – Guardian and hopes to improve it within next year:

  • Real-time feedback on product availability

  • If not, notify maintenance personnel immediately

  • Can quickly assist in locating errors if not available

Frontend – Guardian is intended to be as simple as possible as a real-time monitoring and regression testing tool. Large companies can build their own systems or extend them based on excellent tools such as Falcon, but small companies, especially in the early stages, want to achieve online quality assurance as cheaply as possible.

read

  • Yu Stream: Vue 2.0, progressive front-end solution

  • Cao Liuyang: Observation of front-end technology in 2016

  • Segmented Front End Engineer: Predicting front end 2017

  • Zhang Xin: General view of front-end technology system

  • JavaScript Frameworks and topics to watch in 2017

  • 2016 Front-end Tool usage Survey Report

  • What was it like to be on the front end in 2016

  • 2016 Front-end learning Roadmap

  • The Web front end is a collection of information and guidance from beginners to experienced drivers

Afterword.

At the end of 2016, as in the past, many excellent summary and inventory articles emerged. The author has been writing this article intermittently for a long time. The company project is in a hurry to go online. During this period of time, after reading a lot of works made by others, I increasingly feel that my pattern and vision are rather low. This is why I have always mentioned in the article that my experience and feelings come from small and medium-sized creative teams. I hope I can have the opportunity to further expand my vision next year. If any of the reading partners have a good communication group recommendation welcome private letter informed, three people, there must be my teacher, I also hope to contact some real god.