Written in the beginning

  • This paper mainly sort out some of the daily development of more frequently used norms, such as: file structure, naming. The views expressed are those of the author.

Related articles

  • Common but overlooked methods for ES6 (Destruct assignments and values first)
  • ES6 Common but ignored methods (second bullet functions, arrays, and objects)
  • ES6 common but ignored methods (third bullet Symbol, Set, and Map)
  • ES6 commonly used but overlooked methods (fourth bullet Proxy and Reflect)
  • ES6 common but ignored methods (# 5 Promise and Iterator)
  • Common but ignored methods for ES6 (Generator 6)
  • ES6 Common but ignored methods (async)
  • ES6 Common but ignored methods (eighth bullet Class)
  • ES6 common but ignored methods (Module 9)
  • ES6 common but ignored method (eleventh bullet Decorator)
  • Common but overlooked approaches to ES6 (End game – Latest Proposal)

File structure

  • In daily project development, most developers do not need to pay attention to the structure of the entire project directory, because the project leader, or other architects, have the entire project file structure. Developers only need to write corresponding modules in their own module directory. So if you need to build a project, how should you design the document structure?

reactProject as an example

  • The project name isdetanx-react.
The entrance
  • detanx-react/index.jsFile, the entry file for the project.
The configuration directory
  • detanx-react/configFolder, used to store some configuration files for the project, such as we usewebpackThe packaging configuration and others such as willreact-router,react-domPackage configuration such as individual packages via gulp.
Package analysis directory
  • detanx-react/analyzFolder, used to store throughwebpackAfter packaging, analyze the files of the packaging process.
Production directory
  • detanx-react/buildordetanx-react/distThe folder is used to store all production files that need to be deployed online after the project development is completed.
The data directory
  • detanx-react/mockFolder. During the development of the project, the progress of the back-end development may not be as fast as that of the front-end, so the interface cannot be debugged, so we can configure it by ourselvesmockData development and debugging. This is where you put all of themmockThe data.
Public directory
  • detanx-react/publicFolders, packaging will require basichtmlTemplates, embedded things likecss,faviconWe can put it under this folder.
Refer to the directory
  • detanx-react/srcThis is the folder that changes the most in our project development. Most of the code we write is under this folder. It has a different structure for different projects.
    1. detanx-react/src/componentsFolders that hold common components for project development.
    2. detanx-react/src/hooksA folder that holds some of the new hooks packaged during development.
    3. detanx-react/src/requestFolder that holds the encapsulation of project requests.
    4. detanx-react/src/routerFolder to store the routing related Settings of the project, configuration can also be writtendetanx-react/configUnder the folder.
    5. detanx-react/src/viewFolder, storing all page content of project development, divided according to each module.
      • Each module can be divided intoindexFile (module entry),componentsFolders (the extracted components that hold the module), etc.
    6. detanx-react/src/commonA folder containing the public contents of the project, such as: public methods (null, data type, etc.), constants (can be multiple (2More than) constants used by different modules, etc.
Static directory
  • detanx-react/staticFolder, this folder can also be placeddetanx-react/srcBelow, use to store some images, fonts,CSS(LESS,SASS), etc.
other
  • Other folders can be added to any directory as appropriate according to your project needs.

named

  • The naming part mainly includes function naming, variable naming, module naming,className (CSSName). If you don’t have a good naming convention and don’t like writing code comments when developing projects, especially in collaboration with multiple people. When you leave a job or need to make a project transition for some other reason, people will be checking in with your family while they’re reading through the code. They’ll probably call you to ask, wasting a lot of each other’s time.

The function name

  • The naming method can be big hump, small hump. A small hump is generally recommended.
  • When we write a function, we should first determine one of the functions of the function, such as determining the type of a value, retrieving data from a table by request, showing or hiding a page, etc. So we can start with different words for different functions, for example:
    1. canDetermine whether an action can be performed (canGetUserName)
    2. hasDetermine if there is a value (hasUserName)
    3. isDetermine whether it is a value (isEmpty)
    4. getGet a value (getUserName)
    5. setSet a value (setUserName)
    6. loadLoad some data (loadUserInfo)
  • It is certainly not possible to cover all the scenarios in the project completely. When we name a function and do not see what it is doing directly, we can explain the function by adding comments to it.
  • Each function should be a separate function, reducing the coupling between functions.
  • The size of each function should not exceed200Line, over should try to extract part of the logic into a new function. You should add appropriate comments to the complex logic.
  • Private methods can be specified between developers at project time, such as using_or$The leading function is private.

Variable naming

  • During project development, many developers simply name a variable to make things easier. For example, it may only be used to receive the return value of a functionaI’m only going to use it once; And then one is some count variable just oneiOr any other letter. When your module is covered in these variables, your code is a disaster for others to see.
  • We can use var or let to declare common variables. When naming a variable, we should name it by the type of the variable or its usage scenario, and try to make the semantics clear. Such as:
    1. Boolean type:isShowModal(Whether to display pop-ups)
    2. Array type:userLists(User list)
    3. Object type:userInfoObjUser information object, although we generally knowuserInfoIt’s just an object, I’m just saying a name that if you don’t see it, you can put an identifier behind it.)
    4. SymbolType:userNameSym(SymbolType of user name)
    5. , etc.
  • Variables must be named with letters and underscores_or$Is usually agreed at development time_or$The leading variable is private.
  • When naming variables, try to ensure that there are no numbers in the name. For example:list1,list2And so on.
  • Constants should be all larger and underlined for each word (WARNING_DUATION_TIME: Warning display time).

The module name

  • In order toreactFor modules, we should name each module with a big hump (UserConfig), and the module name should be semantically representing the content of the module, for example (UserConfig) represents the user’s configuration module.

className (CSSName)

  • CSSNaming is what we usually useBEM(block (block), elements (element), modifiers (modifier) naming conventions.
    .block {}
    .block__element {}
    .block--modifier {}
    Copy the code
    • blockRepresents a higher level abstraction or component.
    • block__elementOn behalf of.blockThe offspring used to form a complete.blockAs a whole.
    • block--modifierOn behalf of.blockDifferent states or versions of.
  • Using two hyphens and underscores instead of one allows your own blocks to be delimited by a single hyphen.
    .sub-block__element {}
    .sub-block--modifier {}
    Copy the code
  • The advantages and disadvantages:
    1. Advantages: More description and clearer structure, and the meaning of a tag can be known from its name.
    2. Disadvantages: When nesting is too deep,classThe name can be very long, which can be resolved by other conventions, such as reducing the level.
  • use
    1. Timing: when relational module relationships need to be identified.
    2. Processing: passLESS/SASSTo be written in a preprocessor languageCSS.

Code specification

  • ES6- Programming style
  • In development, if there are no plug-ins that use some code specifications, multiple developers will write code with several styles, so when we collaborate in development, we need to agree on code specifications, for examplejsthrougheslintTo constraints,tsCan be achieved bytslintConstraints, we only need one person to configure the corresponding constraint configuration file.
  • But some code is written without these constraints, just implementation. Here are some code specifications (not necessarily ones that constraints can’t do).

An example use of ESLint

  • ESLintIs a syntax rule and code style check tool, can be used to ensure that the writing of correct syntax, style uniform code.
  • The installationESLint.
$ npm i -g eslint
Copy the code
  • The installationAirbnbGrammar rules, as wellimport,a11y,reactThe plug-in.
$ npm i -g eslint-config-airbnb
$ npm i -g eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react
Copy the code
  • Create a new one under the root of your project.eslintrcFile, configurationESLint.
{
  "extends": "eslint-config-airbnb"
}
Copy the code
  • vscodeInstalled in theeslintPlugins can be checked while writing.

quotes

  • Quotation marks are divided into single quotation marks (') and double quotation marks ("), andES6The new template string is represented by ‘ ‘, which is probably mostly used in development. In general,.js,.ts,.jsx,.tsx,.vueCan write such asjsFile, usually using single quotation marks ('),htmlIn (tag attributes, etc.) using double quotation marks ('). Can replace the previous continuous string concatenation operation.
export default class extends PureComponent { constructor() { this.state = { value: 'detanx', list: null } } render() { const { value, List} = this.state return (<> <div className="detanx">{value}</div> </>)}} // ' 'let user = 'my name is' const name  = 'detanx'; // es5 user = user + ' '+ NAME; // es6 let user = `${user} ${NAME}`Copy the code

variable

  • The variable naming convention was mentioned above, but here is the use of variables. We write code now should use as much as possibleletandconstDeclare variables instead of usingvar.
  • All variables should be declared before they are used.
  • More than2That we should useconstDeclared at the top level of the currently used module, multiple modules used should be declared in the file’s public module constant file.
  • To declare a variable, you should assign it an initial value.
// bad
let i
for(i = 0; i < 10; i ++) { ... }

// good
let i = 0; 
for(; i < 10; i ++) { ... }

for (let i = 0; i < 10; i ++) { ... }
Copy the code
  • useconstWhen declaring multiple values in a row, you can use arrays to deconstruct assignments.
// bad
var a = 1, b = 2, c = 3;

// good
const a = 1;
const b = 2;
const c = 3;

// best
const [a, b, c] = [1, 2, 3];
Copy the code

Deconstruction assignment

  • Destruct assignment is preferred where it can be used. For example, the multiple aboveconstThe statement.
    1. When an array member assigns a value to a variable, destruct assignment is preferred.
    const arr = [1, 2, 3, 4];
    
    // bad
    const first = arr[0];
    const second = arr[1];
    
    // good
    const [first, second] = arr;
    Copy the code
    1. Function arguments that are members of an object use destruct assignment preferentially.
    // bad
    function getFullName(user) {
      const firstName = user.firstName;
      const lastName = user.lastName;
    }
    
    // good
    function getFullName(obj) {
      const { firstName, lastName } = obj;
    }
    
    // best
    function getFullName({ firstName, lastName }) {
    }
    Copy the code
    1. If a function returns more than one value, use the deconstructed assignment of an object over the deconstructed assignment of an array. This makes it easy to add the return values later and change the order in which they are returned.
    // bad
    function processInput(input) {
      return [left, right, top, bottom];
    }
    
    // good
    function processInput(input) {
      return { left, right, top, bottom };
    }
    
    const { left, right } = processInput(input);
    Copy the code

object

  • An object defined on a single line where the last member does not end in a comma. An object defined on multiple lines with the last member ending in a comma.
// bad
const a = { k1: v1, k2: v2, };
const b = {
  k1: v1,
  k2: v2
};

// good
const a = { k1: v1, k2: v2 };
const b = {
  k1: v1,
  k2: v2,
};
Copy the code
  • Objects should be as static as possible; once defined, new attributes should not be added arbitrarily. Use if adding attributes is unavoidableObject.assignMethods.
// bad
const a = {};
a.x = 3;

// if reshape unavoidable
const a = {};
Object.assign(a, { x: 3 });

// good
const a = { x: null };
a.x = 3;
Copy the code
  • If an object’s attribute name is dynamic, you can define it using an attribute expression when creating the object.
// bad
const obj = {
  id: 5,
  name: 'San Francisco',
};
obj[getKey('enabled')] = true;

// good
const obj = {
  id: 5,
  name: 'San Francisco',
  [getKey('enabled')]: true,
};
Copy the code
  • In the code above, the last property name of object obj needs to be computed. In this case, it is best to use an attribute expression that defines the attribute along with other attributes when creating an OBJ. In this way, all attributes are defined in one place.

  • Object attributes and methods, as far as possible concise expression method, so easy to describe and write.

var ref = 'some value'; // bad const atom = { ref: ref, value: 1, addValue: function (value) { return atom.value + value; }}; // good const atom = { ref, value: 1, addValue(value) { return atom.value + value; }};Copy the code

An array of

Using extension operators (…) Copy the array.

// bad
const len = items.length;
const itemsCopy = [];
let i;
for (i = 0; i < len; i++) {
  itemsCopy[i] = items[i];
}
// good
const itemsCopy = [...items];
Copy the code
  • useArray.fromMethod to convert an array-like object into an array.
const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);
Copy the code

function

  • When anonymous functions are used as arguments, use arrow functions instead.
// Execute function immediately (() => {console.log('Welcome to the Internet.'); }) ();Copy the code
  • All configuration items should be grouped in one object and placed in the last parameter. Booleans should not be used as parameters directly.
// bad
function divide(a, b, option = false ) { ... }
// good
function divide(a, b, { option = false } = {}) { ... }
Copy the code
  • Do not use in function bodiesargumentsVariable, usingrestOperator (.) instead. becauserestThe operator explicitly indicates that you want to get arguments, andargumentsIs an array-like object, andrestThe operator can provide a real array.
// bad function concatenateAll() { const args = Array.prototype.slice.call(arguments); return args.join(''); } // good function concatenateAll(... args) { return args.join(''); }Copy the code
  • Use default value syntax to set default values for function arguments.
// bad
function handleThings(opts) {
  opts = opts || {};
}
// good
function handleThings(opts = {}) { ... }
Copy the code

Structure of the Map

  • Pay attention to distinguish betweenObjectMapIs used only when simulating real world physical objectsObject. If it’s just a needkey: valueData structure, usingMapStructure. becauseMapThere is a built-in traversal mechanism.
let map = new Map(arr);
for (let key of map.keys()) { console.log(key); }

for (let value of map.values()) { console.log(value); }

for (let item of map.entries()) { console.log(item[0], item[1]); }
Copy the code

The module

  • useimportreplacerequire.
// bad
const moduleA = require('moduleA');
const func1 = moduleA.func1;
const func2 = moduleA.func2;

// good
import { func1, func2 } from 'moduleA';
Copy the code
  • useexportreplacemodule.exports.
// commonJS const React = require(' React '); const Breadcrumbs = React.createClass({ render() { return <nav />; }}); module.exports = Breadcrumbs; // ES6: import React from 'React '; class Breadcrumbs extends React.Component { render() { return <nav />; }}; export default Breadcrumbs;Copy the code
  • If the module has only one output value, use export default. If the module has multiple output values, use export. Export default and ordinary export should not be used at the same time.

  • Do not use wildcards in module input. This ensures that you have an export default in your module.

// bad
import * as myObject from './importModule';

// good
import myObject from './importModule';
Copy the code
  • By default, the module outputs a function whose name should start with a lowercase letter. The default output is an object. The first letter of the object name should be capitalized.
function makeStyleGuide() { ... }
export default makeStyleGuide;

const StyleGuide = {
  es6: {
  }
};
export default StyleGuide;
Copy the code