This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021.

Hello everyone, I am zhang Three years old 🤣, a French front-end ⚖️. Love share 🖋️, love ice ice 🧊🧊. Welcome friends to add my wechat: Maomaoibingbing, pull you into the group, discuss together, look forward to growing with you 🥂.

preface

I believe all of you are familiar with the project development specifications. Good development specifications can improve the comfort of developers and the maintainability of the code. This article will take a look at the development specifications from the perspective of a front-end developer on the React project.

Note: this article mainly combs the specification list, the example will use the simplest form, the detail part does not do too much extension, some chapters have the good article recommendation. Due to my limited level, there are inevitably omissions in the narration. Please forgive me. I would also like to thank Coder_Q, who plays guitar, for guiding me and correcting me so that I can develop the specification to the next level.

I. Origin and Mission

1.1 Origin of development specification

In the daily development process, it is inevitable to encounter the situation of collaboration with others, such as the collaboration between front-end developers, back-end developers such as collaboration with the position; There will also be cross-job collaborations between the UI and front end developers, and front end developers and back end developers. For the task of job division, process division, stage division we temporarily called project process management, and task development stage management is the focus of this paper. The necessary means of development stage management is to formulate development specifications.

1.2 Mission and future of development specifications

The mission of a development specification is to:

  • Custom unified standard
  • Improve code maintainability
  • Reduce the cost of reader comprehension
  • Improve project scalability

In today’s code ecosystem, developers are looking for code

  • Open source
  • efficient
  • Easy to maintain
  • extensible
  • The canonical

For us as developers, we need to embrace development norms as much as possible, because it’s not just the way things are, it’s the way things are.

Two, front-end project development specifications

2.1 Formulate normative principles

Practice is the sole criterion for testing truth — Guangming Daily

Truth without practice is just empty talk. We need to flexibly formulate norms for different projects. The principles for formulating norms are as follows:

  • Reduce the cost of reader comprehension
  • Solve or avoid some problems
  • Fits the current project characteristics
  • Conforms to technology stack update trends that may or will occur in the future

There are many specifications, and we just need to choose the one that works best. In addition, don’t be trapped by a set of rules. Rules are designed to serve developers, not hinder them. If a development rule significantly reduces development efficiency, then it is reasonable to question the need for it. Here we have formulated norms three do not advocate:

  • It is not recommended to make meaningless specifications, any specification has a cost of use
  • It is not recommended to develop norms where the benefits far outweigh the costs
  • Don’t advocate specification for specification’s sake, business logic is the core, don’t spend too much time on specification

A question strikes me here: why are more and more good projects using TypeScript when it increases the cost of learning and using it? The answer is that it is also very profitable, improving code robustness and teamwork. However, not all projects are suitable. If the project itself is very small, the added cost of using it may be less than the benefit, so you can choose not to use it. The same goes for specifications, always take cost into account.

2.2 Decoupling, encapsulation and reuse

2.2.1 Relationship among the three

When it comes to specifications, these three mountains are inseparable. Here is my understanding of the relationship between the three: decoupling is for better encapsulation, encapsulation is for reuse (code blocks), reuse is to improve (development) efficiency.

2.2.2 decoupling

Decoupling is an integral part of building highly cohesive, low-coupling modules, such as tool functions. Here are a few examples:

/* Application of decoupling in CSS */

/* a container */
.box {
    / *... * /
    background-color: greenyellow;
}

/* Set the background color to pink */
.background-hotpink {
    background-color: hotpink;
}

/* Set the background color to blue */
.background-sklyblue {
    background-color: skyblue;
}
Copy the code
<div class="box"></div>
<div class="box background-hotpink"></div>
<div class="box background-sklyblue"></div>
Copy the code

The example above takes the code that controls the background color out of its own, which is one of the most common forms of decoupling in CSS.

// Decoupling in JavaScript

/ / before decoupling
const myFun = () = > {
    // Complete A task code...
    // Complete the B task code...
};

// Decoupled into two separate ways to accomplish two different tasks, separate maintenance, more code, more maintainability
const funA = () = > {
    // Complete A task code...
};
const funB = () = > {
    // Complete the B task code...
};
const myFunNew = () = > {
    funA();
    funB();
};
Copy the code

I won’t mention the complicated examples, but I’m sure you all know the practical use of decoupling. Again, don’t over-decouple. After all, the original purpose of decoupling is to better maintain our code, and it depends on the requirements and complexity of the code. Finally, a brief summary of decoupling:

  • You can reduce the complexity of your code and keep one piece of code (one method) focused on one task
  • Facilitate code encapsulation
  • Good for code maintenance

2.2.3 encapsulation

Encapsulation is intended for ease of reuse and maintenance. Let’s look at a simple piece of code:

// Bind a click event to a button

// Get the element method
document.getElementById('myButton').onclick = () = > {
    console.log('Clicked ~');
};

// After wrapping the method, add onclick to the element
const handleClickMyButton = () = > {
    console.log('Clicked ~');
};
Copy the code

In contrast, encapsulated code is easier to maintain and reuse. Commonly used methods, hooks, components, etc., can be encapsulated, usually in the development of a module, if it can be found that other components or pages will also be used in the same or partially the same code extracted (may be methods or may be code snippet containing HTML) for encapsulation.

2.2.4 reuse

As the name implies, it is a way to save development costs by using packaged code multiple times. At a small level, there may be multiple encapsulated methods, modules, and components in a single project; In general, a plug-in library composed of multiple methods to solve a class of problems, a UI library composed of multiple components, a whole set of solutions to solve a problem — the framework is the embodiment of reuse. (And the open source spirit, of course)

2.3 Common Modules

In the project, we will encapsulate some global common components, methods and so on for reuse, each module plays its own role. Common common modules are illustrated below.

├ ─ ─... ├─ SRC Heavy Exercises ── Assets Heavy Exercises ── hooks Heavy Exercises ── styles heavy exercises ─Copy the code
  • Assets are global static resources that store files such as pictures and fonts.
  • Components Global public component that holds UI components that are used multiple times in multiple pages/components.
  • Hooks global, store reusable hooks.
  • Services Global public request.
  • Styles Global public styles.
  • Utils global public methods.

2.4 UI componentization

Componentization usually refers to the breaking up of a page into components that are independent of each other and work with each other, as well as the encapsulation of reusable code containing styles for reuse. Here is a simple component split:

// src/pages/Home/index.tsx
/ / the parent component
import { CSSProperties } from 'react';
import Child from './components/Child'; / / child component

const Home: React.FC = () = > {
  const parentStyle: CSSProperties = {
    margin: '50px'.padding: '50px'.fontSize: '24px'.backgroundColor: 'cornflowerblue'};return (
    <div style={parentStyle}>I'm the parent component<Child />
    </div>
  );
};

export default Home;
Copy the code
// src/pages/Home/components/Child/index.tsx
/ / child component
import { CSSProperties } from 'react';

const Child: React.FC = () = > {
  const childtStyle: CSSProperties = {
    marginTop: '30px'.padding: '50px'.backgroundColor: 'skyblue'};return <div style={childtStyle}>I'm a child component</div>;
};

export default Child;
Copy the code

Of course, you can also encapsulate several common components to make your code more reusable and maintainable. A UI library is simply a collection of easy-to-use components. Practice has proved that learning excellent code is easier to improve our technology, recommended reading:

  • Build front-end team component systems from 0 to 1
  • Each front-end deserves its own component library, like having a watermelon every summer 🍉

2.5 Naming Normalization

Good variable names are also critical to normalization, and can be as good as comments. The following is a brief description of the common requirements of naming:

  • meaningful
  • Combinations of English words are preferred
  • Moderate length
  • There are regular
/* ============ these names are not good ============ */

/ / meaningless
// Disadvantages: Easy to confuse, difficult to maintain
const a1, b1, c1;

/ / pinyin
// It is not popular to use pinyin at present
const biaoti, tupian, julao;

// Too simple words
// Disadvantages: easy to duplicate, may be used in a file with many similar names (e.g.
const title, img, name;

// No hump naming
const pagetitle, routeparam, allstatus;

// Too generic name
const myFunction = () = > {};

/* ============ these names really do not poke ============ */

// Common naming rules: prefix + noun
// Strengths: meaningful, moderate length, hump word combinations
const isTitleShow;
const handleSendMsg = () = > {};
Copy the code

If you really don’t know what to call it, you can also use the tool’s website: CODELF

A good developer should have good naming habits.

  • Elegant variable names 🧊🧊

2.6 Proper Directory splitting and naming

2.6.1 Directory Splitting

Module directory

Normally, each module/component has a folder. If you split out the sub-components, you can create the Components folder under the current module.

├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ index.Copy the code

Static Resource directory

Management of static resources is also important. The static assets of a project are typically placed in SRC/Assets and, if unclassified, might look something like this:

├── exercises ─... x100Copy the code

File for a moment, file crematorium. This should be grouped according to the modules in the project:

├─ exercises, exercises, exercises, exercises, exercises, exercises, exercises, exercises, exercises, exercises, exercises ModuleB └ ─ ─...Copy the code

2.6.2 Naming Directories and Files

For directory naming, we should pay attention to the following aspects:

  • Use plural names, such as assets, hooks, images, etc
  • Common public directories should be in lowercase, for example, layouts, Pages, services, and so on
  • Component directories should follow a big camel name, such as UserCenter, AboutUs

When naming files, we should pay attention to the following aspects:

  • The main file of each module should be named index.xxx, so that the name can be used when referring to abbreviations (e.g/ModuleThe equivalent of/Module/index.tsx

2.7 HTML related

We’re not just talking about.html files here, but template in Vue and JSX in React. We need to pay attention to:

  • Use line breaks wisely
  • Nested nodes should be indented
  • Fair usemetaThe label
  • forhtmlTo writelangattribute
  • Attributes on labels are quoted in double quotes
  • The order in which the attributes of the tag are written comes first
  • Try not to use rare tags and incompatible tag attributes
// omit non-important code

/ / a component
// Too many parameters are passed in here
const ArticleItem = (
    {
        item = {},
        type = 'ARTICLE',
        isCurrentUser = false,
        isDel = false,
        titleStatus = false,
        division = false
    }
) = > {
    // ...
};

export default() = > {// Again, use a line break to make it clearer
    return (
        <>
            <ArticleItem
                key={value? .id}
                item={value}
                type={value? .type}
                isCurrentUser={isCurrentUser}
                titleStatus
                division
            />
        </>
    );
};
Copy the code

Htmlelement.lang: Meta tags: htmlElement.lang

2.8 JavaScript related

2.8.1 Modular functions

The more complex the page is built, the more complex the JavaScript is written, and modularity provides a practical and effective solution to reduce the complexity of the program. It supports the import and export of packaged code on demand to improve the reusability of part of the code. Common modular specifications are: CommonJS, AMD, RequireJS, etc.

Recommended reading:

  • JavaScript modules module
  • The loading implementation of Module

2.8.2 Easy to understand

You may think your code is “cool,” but the folks who maintain it 🙂 don’t necessarily think so.

Make your code as simple as possible, and don’t bash your colleagues with the following magic 🧙 :

  • Type 1: Redundant code
  • Type 2: Bad indent line feed
  • Type 3: Variables falling from the sky
  • Type 4: redundant operation
  • Formula 5: Troublesome bit operations
  • Type 6: More than three levels of judgment nesting
  • Rule 7: Completely different from what the notes describe (the most suffocating operation)

2.8.3 Using syntactic sugar and new features

Use the new syntax and features of ES6 and later to make your code simpler and easier to maintain. Here are four popular syntaxes:

/* ============ arrow function ============ */
// before
var oldFunction = function () {
    var _this = this;
    // do something
};
var oldFunction2 = function () {
    return "hello world";
};

// after
const newFunction = () = > {
    // do something
};
const newFunction2 = () = > "hello world";

/* ============ destruct assignment ============ */
// before
var person = {
    name: "Wang Bingbing".sex: "female".job: {
        jobName: "compere",}};var name = person.name;
var sex = person.sex;
var jobName = person.job.jobName;

// after
const {
    name,
    sex,
    job: {
        jobName
    },
} = person;

/* ============ Template string ============ */
// before
var myStr = "world";
var helloWorld = "hello " + myStr + "!";

// after
const str = `hello ${myStr}! `;

/* ============ Short for object properties ============ */
// before
var a1, b1, c1;
var obj = {
    a1: a1,
    b1: b1,
    c: c1
};

// after
cosnt obj = {
    a1,
    b1,
    c1
};
Copy the code

Recommended reading:

  • 15,000 words encapsulates all ES6 features
  • If you know how to use ES6, use it!

2.8.4 Handling Errors

Error handling and error prevention are important for code robustness. To do this, we need at least:

  • Throw an exception reasonably and make an error prompt
  • For code that can go wrongtry/catch
  • There areThe default dataPlaceholder UIEnsure that the page does not crash in case of an error
  • Distrust any data format returned by the back-end interface (especially arrays) and process the data before using it

Recommended reading:

  • The most complete guide to JavaScript error handling

2.8.5 Unit Test

To ensure the overall robustness of your code, you can do front-end unit testing before committing your code to the repository. The specific operation process of unit testing will not be expanded here, but the JavaScript testing framework Jest official document portal is attached here: www.jestjs.cn/

Recommended reading:

  • Use Jest for React unit tests
  • Front-end testing framework Jest

2.9 Style Correlation

Rules of the summary

CSS preprocessors such as Sass, Less, and Stylus are commonly used in projects. Here Less is used as an example. Generally, we should pay attention to:

  • Uniform naming rules
  • Use nested syntax wisely
  • Define public variables properly
  • Non-last-level elements, with little or no label selectors
  • The component style one-to-one principle, one component for one style file
  • In common components or page-level components, minimize the use of short class names that are easy to repeat, such as box, title, info
  • You can define a non-repeatable class name on the outermost element of a component, freeing up the namespace for class names within the component

Naming rules

We need to develop a uniform and reasonable naming rules for a project, such as the use of a dash or underline split name. To distinguish them from JavaScript variables, camel names are not usually used.

// dash "-" split name
.hd-title {}

// Split the name with the underscore "_"
.banner_box {}
Copy the code

Reasonable nested

Nested syntax, where it exists, must be used. But avoiding deep nesting as much as possible, implementing style requirements with as few class names as possible while maintaining extensibility is a front end challenge.

// The deeper the nesting, the more difficult it is to maintain. This, of course, requires proper DOM element nesting
.classname-a {
    .classname-b {
        .classname-c {
            .classname-d {
                // ...}}}}Copy the code

Optimize the code by using the symbol & instead of the parent element in nesting.

.btn {

    // ...
    &.active {
        color: #0094ff; }}Copy the code

Public variables

The purpose of defining public variables is to facilitate maintenance and avoid the hassle of changing a global color scheme and having to replace each style file. In general, we have the following rules for defining variables:

  • Define different public variables based on actual project requirements
  • Different types of variables have different naming prefixes or suffixes for easy differentiation
  • Different types of variables have their respective roles. If there are too many variables of a certain type, separate them into a file for maintenance
// The following is only sample code

/* ============ layout ============ */
// The spacing is large
@space-large: 36px;

// Spacing - middle
@space-middle: 24px;

// The spacing is small
@space-small: 12px;

/* ============ color match ============ */
/ / theme color
@theme-color: #0094ff;

/ / the base
@background-lightgray-color: #f9f9f9;
Copy the code

Global common style files

Every project has a global style file that holds or references public variables, common class names, common custom class names, and so on. We need to be careful to maintain. (Every common module needs to be carefully maintained to avoid errors.) Here is a sample style file:

// src/styles/index.less
// Global public style

/ /! Use multi-line comments to separate different types of style code, variables first

/ /! This is the first level of classification
/ * = = = = = = = = = = = = = = = = = = = = = = = = public variables = = = = = = = = = = = = = = = = = = = = = = = = * /

/ /! This is secondary classification
/* ------------ layout ------------ */
// Type width
@container-width: 1200px;

// The spacing is large
@space-large: 36px;

// Spacing - middle
@space-middle: 24px;

// The spacing is small
@space-small: 12px;

/* ------------ color match ------------ */
/ / theme color
@theme-color: #0094ff;

/ / the base
@background-lightgray-color: #f9f9f9;

/ / title
@title-color: # 000c;

/ * = = = = = = = = = = = = = = = = = = = = = = = = public class name = = = = = = = = = = = = = = = = = = = = = = = = * /
/* ------------ layout ------------ */
/ / type area
.container {
    margin: 0 auto;
    width: @container-width;
    min-width: @container-width;
}

/ /! This is a three-level classification, and there may be different common class names/utility class names under the same classification
// Margin
.mg-0-auto {
    margin: 0 auto ! important;
}

.mg-b-16 {
    margin-bottom: 16px ! important;
}

.mg-l-auto {
    margin-left: auto ! important;
}

/* ------------ text ------------ */
// Text size
.font-16 {
    font-size: 16px ! important;
}

.font-24 {
    font-size: 24px ! important;
}

// Text alignment
.text-align-center {
    text-align: center ! important;
}

// Single line text beyond hiding
.text-ellipsis {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

/ /! Custom class names are common class names that need to be used in many page components, and should be used sparingly if not necessarily
/* ------------ custom ------------ */
// Public box
.common-box {
    background-color: #fff;
    // ...

    // Gray background color
    &.gray-bg {
        background-color: @background-lightgray-color;
    }

    // Inside the box
    .box-title {
        color: @title-color;
        font-weight: bold; }}Copy the code

2.10 Use of comments

Tens of thousands of lines of code, comment the first line. Code is not standard, colleague tears two lines.

Writing code is best to develop a good habit of annotating, convenient for others to understand your code, but also convenient for later code maintenance. In general, these places need to be commented:

  • The first line of the file identifies the purpose of the file, such as XXX components, XXX styles
  • Split code blocks between different business logic in the same file
  • The first line of the function definition
  • Near the important logical part of a function
  • The line before or after an important variable

Recommended reading:

  • Elegant use of comments 🧊🧊

2.11 Code submission specification

Git commit-m [message] git commit-m [message] Disorganized description information makes it difficult to trace the source of subsequent problems and assign responsibilities. Due to lack of space, this article will not be expanded here. It is recommended that you read the relevant article about code submission specifications:

  • Gracefully Commit your Git Commit Message
  • Git commit specification

2.12 specification related plug-in (VSCode)

2.12.1 Formatting code plug-in

Beautify

Plug-in documentation: Beautify

Plug-in screenshot:

Prettier – Code formatter

Prettier-code formatter prettier-code Formatter

Plug-in screenshot:

2.12.2 Code Style Check

ESLint

Plugin documentation: ESLint

Plug-in screenshot:

2.13 the README. Md

Why README ?

A good project usually has a good documentation. When you browse or maintain a project, the first thing you look at is the description document of the project.

grammar

Markdown is a lightweight markup language that can be used to add formatting elements to plain text documents. Markdown was founded by John Gruber in 2004 and has become one of the most popular markup languages in the world. — MarkDown Chinese

For more information about Markdown, please visit Markdown’s Chinese website.

The basic composition of

A good project document generally includes the following:

  1. Project introduction (including project name, logo, introduction, official website and other basic information)
  2. Using the Technology stack
  3. Installation and operation
  4. Project features, project function list
  5. FAQ
  6. Update log

Recommended reading:

  • Why is someone else’s open source project documentation so cool? This is the artifact used!
  • VuePress teaches you how to build a vUe-like document style technical document/blog

2.14 Code specification documentation

To learn Code specifications more systematically, I strongly recommend friends to go to Code Guide here to see, full of dry goods! Here is a screenshot of the site:

Connect with UI designers

Front-end specification and UI design

Generally, a project will have a set of design principles for UI design, i.e. a set of stylitically consistent components, color schemes, distances, fonts, etc. For front-end developers, components are typically provided by open source UI libraries, and we need to worry about the remaining specifications, defining the corresponding variables to control them. Below is an example of color design specification (part) of the project:

I work with the QA of UI designer Jun Brother

Q&a background

The beauty of a page largely depends on the inspiration of the UI design, but the unity of the style of the page depends on the UI design specification. Front-end developers can define common variables and encapsulate common components according to the common part of the style in the process of project development. From the perspective of the development process, if UI designers can provide a complete set of style design specifications, it will greatly reduce the front-end developers’ later maintenance requirements. An important part of the development process is communication. With such a mood, I started a q&A with jun Ge, UI designer of the project team.

Question 1: Based on your work, what do you think the front-end specification should pay attention to in the UI part?

All very important. A complete design specification is designed according to the atomic design theory, which is organized into modules composed of molecules and atoms in the interface. Atoms are the basic component of all substances, and it is impossible to form a whole molecule if only one atom is paid attention to. — Jun, UI designer

Question 2: Do you think the benefits outweigh the costs of providing a front-end development specification (UI) for each project?

I think development specification consistency is more important is to solve the user experience, and convenient maintenance, in the late to make design iterations is more seamless handover, make each stage of the design changes have can reference standard, reduce the design cost, improve the efficiency of design, won’t make change from integral style, at the same time make the designer is not spending more time on the style, Think more about business and experience. — Jun, UI designer

summary

Having said all that, there are still three steps to the specification: make the specification, follow the specification and maintain it. All three steps are important. There are many specifications on the market, choose according to the actual requirements, do not choose two conflicting specifications. There are norms not to comply with is no norms! Finally, I realized that everything is not perfect, so is the program and code, but we can improve it step by step, many excellent projects are continuous iteration. Finally, I hope you can have a harvest after reading this article, thank you!

The resources

  • Code Guide
  • MDN Web Docs
  • MarkDown Chinese website