preface

Good books are divided into chapters, good code into modules, so what defines a good architecture?

Cough cough, do not mean, the topic from big ~~ young generation, dare to talk about the framework.

However, many people think that the front end is nothing more than HTML+CSS+JS, a directory like file, there is no architecture at all. But I want to say… You’re right!

However, THE author has been exploring different organizational forms of page structure. In my humble opinion, a good structure can facilitate expansion and development as well as later project maintenance.

At the beginning of my contact with the front end, I have been thinking about what kind of architecture is more comfortable and easy to expand, and can accommodate B. The React – Full – Dianping – wrote to React in the Demo + React redux + soga some of the code of the organization’s thinking: the React technology stack project structure is explored

I’m still learning, and this article is just a look at some of the ways I organize my code this time around as I develop a page. To throw a brick

I hope you will not add your comments.

The project architecture

SRC ├─ Moving-log ├─ constants. Ts │ ├─ ├─ app.js ├─ app.json ├─ Common │ ├─ Animation-utils Constants. Ts │ ├─ Detail-Utils. Ts │ ├─ Net utils. Ts │ ├─ price-utils Storage - utils. Ts │ ├ ─ string - utils. Ts │ ├ ─ time - utils. Ts │ ├ ─ the ts │ ├ ─ url - utils. Ts │ └ ─ utils. Ts ├ ─ components │ ├ ─ Loading - page │ │ ├ ─ index. CSS │ │ └ ─ index. The TSX │ └ ─ PM - bottom │ ├ ─ index. The CSS │ └ ─ index. The TSX ├ ─document│ └ ─ index. The JSX ├ ─ event │ └ ─ EVENTS. The ts ├ ─ modules │ ├ ─ bottom - action │ │ ├ ─ index. The CSS │ │ └ ─ index. The TSX │ └ ─ Page - the container │ ├ ─ base │ ├ ─ decorator │ ├ ─ index. The TSX │ └ ─ libs └ ─ pages ├ ─ buyer - identity │ ├ ─ components │ ├ ─ Constants │ ├─ Customized -hooks │ ├─ index. TSX │ ├─ types │ ├─ utilsCopy the code

Maybe it doesn’t look very intuitive, but take a screenshot to explain

Take a look at it, and have an idea of where it is and what each file does. Now let’s go to the details

Directory duties

In fact, divided so many directories, nothing more than for maximum possible reuse. It also includes the extraction of component state and the use of hooks features.

Public logic outside the Pages layer

After all, it is an MPA application, so everything is still around pages.

action-log

First of all, I won’t say much about the action-log directory here, because there’s not much to learn from it. An ActionLog object is returned to perform some logical processing such as business burying, information gathering, etc. So if you have some common base class wrapper, you can put it there.

common

Common ├─ Animation - Utils. Ts ├─ Business-Utils. Ts ├─ Detail-Utils. Ts ├─ Net - Utils Price - utils. Ts ├ ─ storage - utils. Ts ├ ─ string - utils. Ts ├ ─ time - utils. Ts ├ ─ the ts ├ ─ url - utils. Ts └ ─ utils. TsCopy the code

Due to the complexity of the project, the business logic is relatively more. So here I’ve separated utils by category. Aspect maintenance and expansion in later development, also easy to find.

In addition to the utils that can be distinguished by naming, there is a type.ts and constants. Ts, which are quite handy with their names.

components

The naming of components is familiar to framework users. Yes, it is the encapsulation of some common components, such as the two components I put here loading-page,pm-bottom and other common components. Components is a relatively “small” concept, and the division based on this is simple in this project, whether or not it is a “puppet component” (although after hooks, we are not in a position to say that),

modules

Modules ├ ─ bottom - action │ ├ ─ index. The CSS │ └ ─ index. The TSX └ ─ page - the container ├ ─ base │ ├ ─ base. The TSX │ ├ ─ error. The TSX │ └ ─ ScrollBase. TSX ├ ─ decorator │ └ ─ withError. The TSX ├ ─ index. The TSX └ ─ libs ├ ─ displayName. Ts ├ ─ navbarTransparent. Ts ├ ─ SPM. The ts └ ─ title. TsCopy the code

The typical Page-Contaienr module serves as a generic low-level container for every page. This container was introduced in a previous article, and how to decorate your Typescript with decorators will not be discussed here. It’s basically a encapsulation of some basic functionality. So that means that the directory that explains the event exists.

The biggest difference between Modules and Conponents is complexity and internal state management. If the internal state is complex and has many interactions, we call it a module. Yeah, the lines here, we’re a little blurry.

But when you get a draft of the design, I guess you can understand my good intentions ~

The red box can be understood as module, and the green box can be understood as Components

The organization of the page

For a single page inside the organization, in fact, are very much the same. (Suddenly there’s not much front-end architecture to speak of)

The catalogs are not very differentiated, but they are clear. I will briefly introduce the division of labor in each region, and we will expand it in the follow-up

  • index.tsxPage entry file, but does not write much business logic in itself
  • utilsThe utility functions of the page, including interface requests, dataformatEtc.
  • customized-hooksThe customhooksThere are two, the data needed to initialize the UI (margins, etc.), the business request data.
  • constantsPage constants, including requested onesapi,spmBuried, fixed some of the page business data
  • componentsThe components of the page (note that there are no modules here, because there are too many really confusing things), the pagecomponentsSome are simple and some are complicated.

So that’s some directory structure and code organization. It’s actually fairly simple and clear. Let me introduce you

Page data flow and management rules

You can’t tell me what you’re talking about

Since this is business code, I won’t paste too much code here

Explain the above process briefly

The logic for initializing the UI is business-specific, and there isn’t much to learn from it. What I’m doing in my code here is adapting some UI to the iPhone X.

Let’s focus on the process of initializing interface data. This is essentially the initialization of the state of the components in each page

interface

First we need to define props for each module. After all, because of ts, comments are documentation. Therefore, we defined the props of each component in the type directory. After all, most of the time, the data returned by the interface requires us to make a format, and the purpose of the format is to make better use of components. In other words, these interfaces are reusable! That must be defined outside

Note that the interface has to write comments !!!! The reasons are as follows:

Put all the data processing methods into utils (note the data handling, here I write all the data processing tool functions, and add sufficient unit tests).

True to components, out of the box.

Because there is a constraint between the definition of Type and components, there is a very good constraint for both the use of data inside Componemts and the injection of props when the module is introduced in index.tsX

A reminder at compile time

Error reporting when missing writing

Component communication

Because of the hooks we used and relatively isolated component partitioning, in principle there is not much component communication. Of course, there must be.

In fact, this constraint mainly comes down to the complexity of the service. If the data logic is complex and there is a lot of communication. Consider using useContext and useReducer

Talk about the communication involved in this requirement.

Rule: Components manage their state as value as possible.

Following the above principles, the final business interaction logic is managed internally by the component, and the peer communication involved is operated by the parent component. The parent component operates on the principle of just taking the data and not doing any business. (Distance yourself as much as possible)

The constraint

  • indexWrite as little business logic as possible
  • UI initialization and module data initialization need to be customizedhooks
  • Pull out the states as far as possible.componentIt’s too complicated and needs extra extractioncomponentutilscustomized-hooksAnd so on. With reference to the above
  • componentpropsNeed to extract reuse
  • publicutilsMethod to write adequate unit tests
  • publicutilsMethod export should be exported separately (bundleSize), and write comments (reminders at call time)
  • Define as much as possibleinterfaceAnd write comments. Comments, after all, are documents

All of these constraints should be written laterEslintTo impose strong constraints (cough, the basic literacy of the programmer is unreliable)

Finally, looking at the unit tests I am adding, I did find some problems with edge cases in tool functions during the writing of the unit tests

conclusion

According to the above page code organization behind the writing of a page, feel the code organization and state management is still relatively clear. Later, corresponding CLI will be written to automatically generate the page infrastructure, such as pmCli Add Page or pmCli Add com

Because this article is not convenient to paste too much code, so it may be said that some clouds in the fog, there is any doubt, welcome the public number reply [1], join the full stack technology exchange ③ group, exchange together

Finally, this article is a spin, not a specification definition. More constraints and organization, I hope we can communicate more and learn from each other.

Study and communication

  • Pay attention to the public number [full stack front selection], get good articles recommended every day
  • Add wechat id: is_Nealyang (note source) to join group communication
Public account [Full stack front End Selection] Personal wechat 【is_Nealyang】