preface

There is less individual development and more teamwork in project development. In teamwork, different programmers have different development habits, which can make it difficult to read other members’ code.

In order to produce readable, uniform code in a team collaboration, we need to have some code specifications in the team.

HTML report

HTML element tags are the basis for creating projects on the Web. If we get the initial markup right, we can write more extensible CSS and JavaScript code.

semantic

We need to use the element in its original meaning when it was created, not the full-text div and P elements.

// bad
<div id='header' >
	<div id='header-screen'>
    	<div id='header-inner'>

// good
<header>
	<section>
    	<nav>
Copy the code

Document specification

Document declaration type
to turn on standard mode.

If you do not add this declaration, the browser will turn on weird mode and render the page according to the browser’s own parsing method, which may have different styles under different browsers.

Meta information

Defining character encoding

We use UTF-8 encoding to avoid garbled characters.

<meta charset="utf-8" />
Copy the code

IE Compatible mode (X-UA-Compatible)

We set x-UA-Compatible to enforce browser rendering, and here we use the latest version of Internet Explorer and Chrome more. You can read about it here.

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
Copy the code

Separation of structure, performance and behavior

Try to include only structured HTML in your documents and templates; And move all of the presentation code into the style sheet; Move all the actions into the script.

HTML is all about content

HTML only displays display content. Don’t try to solve visual design problems by introducing specific HTML structures, but try to solve them with CSS.

// bad
<span class="text-box">
  <span class="square"></span>
  See the square next to me?
</span>
// css
.square {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  background-color: red;
}

// good
<span class="text-box">
  See the square next to me?
</span>
// css
.text-box:before {
  content: "";
  display: inline-block;
  width: 1rem;
  height: 1rem;
  background-color: red;
}
Copy the code

CSS article

When setting styles, we encounter some problems:

  • Selector preference. Whether it’s an ID or a class name, priority matters when writing a selector
  • Location dependent. The selector path is related to the position of the HTML element, meaning that the element changes and the style may change
  • Multiple inheritance. There are multiple sources of style for a certain type of element, and changes in one source may also affect the element style change

We can adopt some measures to solve these problems.

Modular CSS

Modular CSS works with HTML markup to make markup clearer, more “modular” and easier to understand.

Of course, there are many such methods. One project may fit with one method, but another project fits with other methods, so we can independently choose the design method according to the actual needs.

OOCSS(Object-oriented CSS)

The OOCSS approach has two principles:

  • Separate structure and appearance. Define a facade as a reusable unit or skin
  • Separate containers and contents. Do not use HTML elements as style constraints
<div class="toggle simple">
  <div class="toggle-control active">
    <h2 class="toggle-title">Title 1</h2>
Copy the code

Here, simple uses a right Angle, and switching simple can be seen as switching skins; Toggle_title is used to set text styles, regardless of whether the text element is div or H2.

SMACSS(Scalable and Modular Architecture for CSS)

SMACSS stands for extensible CSS approach to modular architecture. The style system is divided into five different categories:

  • The foundation. That is, without adding CSS categories, what styles will HTML elements display
  • Layout. Divide the page into sections
  • The module. Modular, reusable units in design
  • State. The presentation style of a module or layout in a particular state or situation
  • The theme. An optional visual appearance layer that can switch between different themes
<div class="toggle toggle-simple">
  <div class="toggle-control is-active">
    <h2 class="toggle-title">Title 1</h2>
Copy the code

SMACSS has a lot in common with OOCSS, except that SMACSS divides code into categories. The biggest difference is that SMACSS uses the state of submodules and is prefixes, while OOCSS uses skins.

BEM(Block Element Modifier)

BEM method, it is recommended that each element have the following CSS class name:

  • Block. Name of the owning component
  • Elements. The name of the element in the block
  • The modifier. Any modifiers associated with blocks and elements
<div class="toggle toggle--simple">
  <div class="toggle_control toggle_control--active">
    <h2 class="toggle_title">Title 1</h2>
Copy the code

The advantage of BEM is that we can clearly understand the meaning of the class name, which, of course, makes the class name seem redundant and redundant.

Single responsibility principle

Everything you create must be single, highly focused, and styles for a selector should be created for a single purpose.

<div class="calendar">
  <div class="primary-header">This is calendar.</div>
</div>

<div class="blog">
  <div class="primary-header">This is blog.</div>
</div>

.primary-header {
	color: red;
	font-size: 2em;
}
Copy the code

In the example above,.primary-header is used on more than one unrelated element, which does not satisfy our single responsibility principle. We can make the following modifications:

<div class="calendar">
  <div class="primary-header">This is calendar.</div>
</div>

<div class="blog">
  <div class="primary-header">This is blog.</div>
</div>

.primary-header {
	color: red;
	font-size: 2em;
}

blog .primary-header {
	color: red;
	font-size: 2em;
}
Copy the code

However,.primary-header can cause multiple inheritance problems, which can be addressed by adding a single task to each CSS class name.

<div class="calendar">
  <div class="calendar-header">This is calendar.</div>
</div>

<div class="blog">
  <div class="blog-header">This is blog.</div>
</div>

.calendar-header {
	color: red;
	font-size: 2em;
}

.blog-header {
	color: red;
	font-size: 2em;
}
Copy the code

Javascript article

named

Naming is generally divided into two kinds:

  • Small hump naming: lowercase first letter, e.guserName
  • Big hump naming: capital letters, e.gUserName

Variable naming

Naming method: small hump naming method

Naming conventions: How the type + object is described. If there is no explicit type, use a noun + object description.

Recommended writing:

type writing
array a/arr
boolean b/is
string s/str
Number (integer) n
Number (floating point number) f
object o/obj
function fn
Date d/date
RegExp r/re

In addition, when we name variables, we should make the variable names have a symbol of intention, so that people can easily search and understand.

const sUserName = 'tom'
const isRead = true

// Use nouns as prefixes
const userTable = 'talbe'

// If the description object is complex, add s
const userTables = ['talbe1'.'table2']
Copy the code

Constant named

Naming conventions: all uppercase + underscore

const USER_ADDR = 'Beijing'
Copy the code

The function name

Naming method: small hump naming method

Naming conventions: the way verbs + methods are described.

Recommended verbs:

The verb describe The return value
is Whether it is a value Boolean value
can Whether an operation can be performed Boolean value
has Is there a certain value Boolean value
set Set a value Returns no value, whether the setting was successful, or the chained object
get Get a value A Boolean value
function setName(name) {
	this.name = name;
}

function getName() {
	return this.name;
}
Copy the code

If a constructor, use the big camel case.

function Student(name, age) {
	this.name = name;
    this.age = age;
}

const oStudent = new Student('Tom'.18);
Copy the code

Class and member naming

In ES6, you can create classes using class and set private/public attributes.

Public attributes: same variable naming method/function naming method.

Private attribute: prefix (_)+ public attribute naming method.

class Student {
	static getId(){
        console.log('getId')
    }
	
	private _name = 'Tom';
    
    public getName() {
    	return this._name; }}Copy the code

Variable declarations

Be careful with global variables

Global variables are the devil.

If you accidentally change a global variable at one point in your code, it can cause other modules that rely on global variables to fail, and the cause of the error is hard to find.

So what should we do about it?

  1. Whenever possible, create a global variable in which other objects and functions can reside.
// bad
const like = 'football';

function likeDo(){
    alert(like);
}

// good
const myInfo={
    like:'football'.likeDo:function(){alert (this.like); }}Copy the code
  1. Using module mode

In ES6, we generate modules through import/export, which allows us to place the required information in a module, almost completely blocking out the use of global variables.

// myInfo.js

export const like = 'football';

export function likeDo() {alert (this.like);
}

// test.js
import { likeDo, like } from 'myInfo';
Copy the code
  1. closure

Of course, sometimes we can reduce global variable information with closures. However, we also need to be aware of memory leaks when using closures.

const myInfo = (function () {
	const like = 'football';
    return {
    	like,
        likeDo: () = >{ alert(like); }}}) ();Copy the code

Declare variables using let/const

We used to use var to declare variables, but after ES6, let/const should be used as much as possible.

When we use var, there will be variable promotion, which can lead to some misunderstandings; Also, when var is applied to the global scope, a new global variable is created as an attribute of the global object, which can inadvertently overwrite a global variable.

// in the browser
var RegExp = 'hello';
console.log(window.RegExp) // hello

const RegExp = 'hello';
console.log(window.RegExp) ƒ RegExp() {[native code]}
Copy the code

Use strictly, etc

When we use == to determine that two variables are equal, if they are not of the same type, we will trigger a JavaScript cast that does not match our expectations (see the details here). This does not happen when we use strict equal ===.

// bad
0= ='0' // true
0= =' ' // true

// good
0= = ='0' // false
0= = =' ' // false
Copy the code

Do not use the eval() function

The eval function evaluates a string and executes the JavaScript code inside it, which can be a security risk.

Code style and review

The above can be considered some of the most compelling, but we still face some soul-searching:

  1. Do you indent with Spaces or tabs? Spaces, two Spaces or four Spaces?
  2. Do YOU need a semicolon at the end of a sentence?
  3. Is there a maximum of 100 or 80 lines per line?
  4. .

These are the kinds of questions that programmers can debate endlessly, with countless pros and cons for each question. I’m not going to say which method is the right one, because the JavaScript engine will execute the worst code if it’s legal.

However, in order for our code to be easy to read, we need a uniform style and a variety of tools for inspection.

JSLint

Early on, we used JSLint to check the quality of our JavaScript code. It reads the source file and scans it, and if there is a problem returns a message describing it and indicating the approximate location of the problem in the source file.

However, JSLint does not support rule customization and must follow the rules provided by the author.

JSHint

JSHint JSHint is based on JSLint and provides flexibility to customize rules. However, JSLint was developed based on JSLint and naturally inherits some of the original problems. JSHint does not support ES6 well enough and does not support JSX.

ESLint

ESLint is a static analysis tool for JavaScript code developed by Nicholas C. Zakas in 2013. It was originally intended to allow developers to customize their own linting rules.

It provides a fairly complete plug-in mechanism that can be freely extended to dynamically load configuration rules. It has both the high configurability of JSHint and full support for ES6 syntax and JSX, arbitrary phase ECMAScript features through the plug-in mechanism.

That’s the tool we’re using right now.

TSLint

TSLint is used to do static analysis of TypeScript code. Later we will use ESLint and add TSLint detection plugins to ESLint.

Prettier

Prettier Prettier is a code formatter that makes output consistent by specifying rules, such as wrapping for maximum number of lines, adding semicolons at the end of sentences.

Prettier can be used with ESLint, and you can click here to see how it works.

conclusion

We briefly summarized the different principles, specifications, and inspection tools for HTML, CSS, and JavaScript in the project.

Of course, this is not a definitive solution in the sense that each team and project can design their own unique specifications. As long as it improves the code quality of our project and facilitates communication and collaboration between teams, all solutions are feasible.

reference

  • Front-end Architecture Design by Micah Godbolt
  • Front-end development specifications: naming specifications, HTML specifications, CSS specifications, JS specifications
  • Code-review previous end code specifications