The Book of Rites: The Doctrine of the Mean

In the early days, when the team was small, there were not too many norms. When encountering problems, you could solve them in the way you were best at. As companies grow and teams get bigger, there are more and more problems caused by not having a uniform code, for example

  • Component library is developed repeatedly, different groups have their own strengths and weaknesses, but the overall quality is lacking
  • Between different businesses, projects can not be reused directly, requiring a lot of development and transformation
  • Getting started is expensive, and each project requires a deep understanding of its code and configuration, not a complete understanding of the business
  • Some automated performance improvement tools cannot be implemented because business projects do not have specifications
  • Wait…

Based on these problems, in the first half of last year, we developed a rotating front-end development specification, after this half year of practice, achieved the expected effect. Next, I will introduce the specific front end development specifications around, hoping to give you some help. Before we also shared around the middle background specification construction, interested can poke this

What the specification contains

Let’s take a look at the specification architecture diagram for an intuitionAs shown in the figure above, we divide specifications intoFive categories

  • The development of specification
  • Monitoring specification
  • Collaborative specification
  • The process specification
  • Open source code

Under each category, there are several sub-categories. In this article, I will introduce some key specifications and their contents in detail. For non-key specifications, we will open source the documents to Github later, and you can check them by yourself.

The development of specification

Local storage specification

It mainly includes the use specification of localStorage to avoid the problems encountered when using storage

Use of the base library

Local storage was implemented using Localforage, which prioritized Using IndexedDB to expand local storage, and handled exceptions using an elegant downgrade scheme.

Storage overflow problem

LocalStorage has storage limits. Therefore, when the storage space is used up, a QuotaExceededError error is reported after the setItem operation.

In fact, localStorage cannot be read or written in traceless mode in some browsers (such as Safari on iOS 11), and setItem will result in the same QuotaExceededError error.

To avoid these situations as much as possible, or to handle them gracefully when they occur, follow the following specifications:

  • Set the expiration time. Encapsulate stored data in the following manner and clear expired data when appropriate.
const data = {
  data: Object.expiredTime: Date.now() + 7 * 24 * 60 * 60 * 1000
}
Copy the code
  • withtry... catchThe parcelsetItemoperation
try {
  localStorage.setItem('my_data'.JSON.stringify(data))
} catch (e) {
  // Error handling
}
Copy the code

Common error handling methods are: clean up expired data and try again; Dump to sessionStorage, custom global object myStorage, Vuex, etc., but remember to read as well.

Storage key overwrite problem

The key must be named according to the following specifications: Service line name_Project Name_Custom name

const PREFIX = 'platform_book_'

try {
  localStorage.setItem(PREFIX + 'my_data'.JSON.stringify(data))
} catch (e) {
  // Error handling
}
Copy the code

Annotation specifications

Proper comments can improve the readability and maintainability of your code.

Principles of annotation

  • Don’t add comments if you don’t have to, go for self-commenting code
// bad
// If the data is ready, render the table
if (data.success && data.result.length > 0) {
  renderTable(data);
}

// good
const isTableDataReady = data.success && data.result.length > 0;
if (isTableDataReady) {
  renderTable(data);
}
Copy the code
  • Be as thorough as necessary, and where you need to annotate, be as thorough as possible

Specification of annotations

Follow common style rules, such as certain Spaces and blank lines, to ensure the readability of comments themselves

  • Single-line comments are used//.

Comment lines need to be preceded by an empty line; There needs to be a space between the comment content and the comment character

function getType() {
  console.log('fetching type... ');

  // set the default type to 'no type'
  const type = this.type || 'no type';
  return type;
}
Copy the code
  • Multi-line comments are used/ * *... * /
/** * make() returns a new element * based on the passed-in tag name */
function make(tag) {
  // ...

  return element;
}
Copy the code
  • Annotate with special markup: TODO, FIXME, HACK, etc
// TODO:What else do I need to do here

// FIXME:The implementation here is problematic and needs to be optimized in the future

// HACK:The processing here is to be compatible with low-end Android bugs
Copy the code
  • Documentation class annotations, such as functions, classes, files, events, and so on, use the JSDOC specification
/** * Book class, representing a Book. *@constructor
 * @param {string} title-Book title. *@param {string} author- The author of the book. */
function Book(title, author) {
  this.title = title;
  this.author = author;
}
Copy the code
  • Avoid emotional comments: such as complaints, discrimination, funny
/** * poor VIP **@param update
 * @return {boolean}* /
Copy the code

Browser compatibility specification

Teams should develop their own browser compatibility specifications based on factors such as the percentage of devices used, application types, development costs, and browser market statistics

Overall requirements for both models

Android must be compatible with Android 4.0 or above, iOS must be compatible with 8.0 or above

# .browserlistrc
> 1%
last 3 versions
iOS >= 8
Android >= 4
Chrome >= 40
Copy the code

CSS compatibility requirements

For CSS compatibility processing, we use postCSS Autoprefixer

// postcss.config.js
module.exports = {
  plugins: {
    autoprefixer: {},
    cssnano: {
      autoprefixer: false.zindex: false.discardComments: {
        removeAll: true
      },
      reduceIdents: false}}}Copy the code

Js compatibility requirements

When dealing with JS compatibility, we use Babel to smooth out browser differences.

It is important to note that proxies cannot be degraded. Use with caution.

  • Through the configuration of the service item@babel/preset-envuseBuiltIns: 'entry', corejs: 3To according to.browserslistrcThe introduction ofpolyfill
// babel.config.js
module.exports = {
  presets: [['@vue/app', {
      useBuiltIns: 'entry'}}]]Copy the code
// main.js
import 'core-js/stable'
import 'regenerator-runtime/runtime'
Copy the code

For example, in the Vue project, the configuration of @vue/babel-preset-app is preset to @babel/preset-env, and core-js@3 is used by default

  • In the base library, through configuration@babel/preset-envuseBuiltIns: 'usage', corejs: 3To deal withjsCompatibility issues to reduce project volume
// babel.config.js
module.exports = {
  presets: [['@babel/env', {
      useBuiltIns: 'usage'.corejs: 3}]],plugins: [['@babel/transform-runtime']]}Copy the code

HTTP cache specification

The vast majority of projects around are single page applications, and we have set the following cache specifications based on the project characteristics

Static resource

The resource domain name s1.zhuanStatic.com is forcibly cached through cache-control for 30 days

cache-control: max-age=2592000
Copy the code

The HTML file

HTML files under the domain m.zhuanzhuan.com are cached through Etag negotiation

etag: W/"5dfb384c-4cd"
Copy the code

The compression

All resources have gzip compression enabled

Communication protocol

The default communication protocol used is HTTP2

Editor specification

Use Editorconfig to help you standardize the configuration of the editor

Editorconfig Specifies the configuration

Configuration file.editorConfig

root = true

[*]
indent_style = space                    # Use a space instead of a TAB
indent_size = 2                         # a TAB is replaced by 2 Spaces
end_of_line = lf                        Use the Unix newline character \n
charset = utf-8                         # character encoding UTF-8
trim_trailing_whitespace = true         Remove Spaces at the end of each line
insert_final_newline = true             Add a blank line to the end of each file

[*.md]
trim_trailing_whitespace = false        The #.md file does not remove Spaces at the end of each line
Copy the code

Prettier specification

Prettier is a code formatting tool. Prettier and ESlint go hand-in-hand in a somewhat roundabout unification of styles, but Prettier and ESlint have conflicting rules, and much effort is made to keep configuration rules consistent. But there are still areas of conflict.

The industry has two options

  • A isPrettierGive priority to
  • A isESlintGive priority to

Prettier formatting when fixing errors, ESlint formats the Prettier, ESlint fixes it again, and ESlint takes the lead. So if you encounter unresolvable errors, just change the ESlint configuration.

Prettier Configuration file

// prettier.config.js
module.exports = {
  // Valid closing comma in ES5 (object, array, etc.)
  trailingComma: 'none'.// Instead of indentation, use Spaces
  useTabs: false.// TAB is replaced with two Spaces
  tabWidth: 2.// Semicolons are added only when the syntax might be wrong
  semi: false.// Use single quotes
  singleQuote: true.// Indent script and style tags in Vue files.
  vueIndentScriptAndStyle: true.// A line of up to 100 characters
  printWidth: 100.// The key of the object is quoted only when necessary
  quoteProps: 'as-needed'.JSX uses double quotes instead of single quotes
  jsxSingleQuote: false.// Spaces are required at the beginning and end of braces
  bracketSpacing: true.// JSX tag Angle brackets require line breaks
  jsxBracketSameLine: false.// Arrow functions with only one argument also need parentheses
  arrowParens: 'always'.// The range in which each file is formatted is the entire content of the file
  rangeStart: 0.rangeEnd: Infinity.// There is no need to write @prettier at the beginning of the file
  requirePragma: false.// There is no need to automatically insert @prettier at the beginning of a file
  insertPragma: false.// Use the default line folding standard
  proseWrap: 'preserve'.// Depending on the display style, HTML should be folded or not
  htmlWhitespaceSensitivity: 'css'.// Use lf for line breaks
  endOfLine: 'lf'
}
Copy the code

Git – commit code

There are many different styles of code committing git commit on the team, and some people don’t even have the concept of a commit specification, so it can be very awkward to go back and find out which version of the code had a problem, and it can be difficult to quickly locate the problem. In order to standardize the project, the code submission specification is very important!

We commit code via the commit specification plugin VUE – CLI-plugin-commitlint (modified/packaged based on Xconventional – Changelog-Angular).

Vue – cli – plugin – commitlint is introduced

Vue-cli-plugin-commitlint is written as a VUE plug-in. You can run the vue add Commitlint command to use it directly. If it is not a VUE project, you can also configure it according to the following configuration.

Commitizen Commitlint Xconvention-Changelog-CLI Husky Xconvention-Changelog-Angular package, one-click installation, out-of-the-box code submission specification.

function

  1. Automatic detectioncommitIf it is standard, submission is not allowed if it is not
  2. Automatic promptcommitFill in the format. How to write it without forgetting the specification
  3. integrationgit add && git commitYou don’t need to execute two commands
  4. Automatically generatechangelog

configuration

Scaffold generated projects are included by default, divided into default use and personalized configuration

If it isvue-cli3The project of

Just use it

vue add commitlint
Copy the code

If it is notvue-cli3The project of

npm i vue-cli-plugin-commitlint commitizen commitlint conventional-changelog-cli husky -D
Copy the code

Add it in package.json

{
  "scripts": {
    "log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0"."cz": "npm run log && git add . && git cz"
  },
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"}},"config": {
    "commitizen": {
      "path": "./node_modules/vue-cli-plugin-commitlint/lib/cz"}}}Copy the code

Add the commitlint.config.js file

module.exports = {
  extends: ['./node_modules/vue-cli-plugin-commitlint/lib/lint']};Copy the code

use

npm run cz  # npm run log && git add . && git commit -m 'feat:(xxx): xxx'

npm run log # generate CHANGELOG
Copy the code
  1. The code is submitted NPM run Cz

  1. Selecting a type is automatically asked

  2. (Optional) Scope of impact of this submitted change

  3. (Required) Write a short description of the change

  4. (Optional) Provide a more detailed change description

  5. (Optional) Is there an incompatible change?

  6. (Optional) Whether this change affects some open issues

Changelog demo

The rules

The specification of describe
feat The new feature
fix Fix the bug
merge Merging branches
docs Only modified documents, such as README, CHANGELOG, CONTRIBUTE, etc
chore Change the build process, or add dependent libraries, tools, etc
perf Optimization related, such as improved performance, experience
refactor Code refactoring, no new features or bug fixes
revert Roll back to the previous version
style Only whitespace, formatting indentation, commas, and so on are changed, leaving the code logic unchanged
test Test cases, including unit tests, integration tests, and so on

Vue project specification

The above mentioned some general development specifications, for different types of projects Vue, Vue SSR, React, small programs, etc., have different specifications, next I will take Vue project as an example to continue to talk about development specifications

ESlint specification

ESLint is a QA tool that checks ECMAScript/JavaScript syntax rules and code styles to ensure that syntactically correct and consistent code is written. ESLint is designed to be fully configurable, and its goal is to provide a plug-in for javascript code detection. The rolled ESlint configuration has specific changes based on the Standard rules.

ESlint specifies the configuration file

The 0, 1 and 2 corresponding to each rule indicate the three error levels: OFF, Warning, and ERROR

module.exports = {
  root: true.parserOptions: {
    ecmaVersion: 6.// Specify ECMAScript version 6
    parser: "@typescript-eslint/parser"./ / ts
    sourceType: "module"
  },
  // Global variables
  globals: {
    window: true.document: true.wx: true
  },
  // Compatible environment
  env: {
    browser: true
  },
  / / the plugin
  extends: ["plugin:vue/essential"."@vue/standard"]./ / rules
  rules: {
    // Do not add a semicolon to the end, only if there is a possible syntax error
    semi: 0.// Arrow functions need parentheses (a) => {}
    "arrow-parens": 0.// Two Spaces are indented. Case in switch statements is 1 space
    indent: [
      "error".2,
      {
        SwitchCase: 1}].// Close callback to undefined variables that are not allowed
    "standard/no-callback-literal": 0.// Turn off side effect new
    "no-new": "off".// Turn off the maximum length of each line less than 80
    "max-len": 0.// Function parentheses are preceded by no Spaces
    "space-before-function-paren": ["error"."never"].// Close requires require() in the top-level module scope
    "global-require": 0.// close Close class methods must use this
    "class-methods-use-this": 0.// Close Disables assignment to native or read-only global objects
    "no-global-assign": 0.// Close Disallows the negation operator on the left-hand operand of relational operators
    "no-unsafe-negation": 0.// Disable console
    "no-console": 0.// Disable trailing blank lines
    "eol-last": 0.// Turn off forcing consistent whitespace in comments
    "spaced-comment": 0.// disable reassignment of function parameters
    "no-param-reassign": 0.// Enforce a consistent linebreak style
    "linebreak-style": ["error"."unix"].// Turn off congruence === verification
    "eqeqeq": "off".// Disallow trailing commas
    "comma-dangle": ["error"."never"].// Turn off the camel spelling naming convention
    "camelcase": 0}};Copy the code

Ignore the specification

Gitignore specification

Files and folders that are ignored when synchronizing to the remote repository. The basic configuration is as follows, and each project can be adjusted according to requirements

.DS_Store
node_modules
/dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
Copy the code

Note: Package-lock. json is not recommended to be ignored. See related discussions. Should package-lock.json be written into.gitignore? www.zhihu.com/question/26…

Eslintignore specification

Files and folders to be ignored during esLint validation. The basic configuration is as follows, and each project can be adjusted according to requirements

node_modules
dist/
test/
lib/
es/
Copy the code

Vue project directory specification

├ ─ ─ dist// [generate] package directory├ ─ ─ the SRC// Required│ ├ ─ ─ views// [Mandatory] Page component. Other types of components are not allowed│ ├ ─ ─ the components// [Required] The business component must be written here│ ├ ─ ─ libs// [optional] Public library (generally used to encapsulate some libraries)│ ├ ─ ─ utils// [optional] Tool library (for libraries such as some function methods)│ ├ ─ ─ assets// [Optional] Public resources (webpack-processed resources referenced by the project)│ ├ ─ ─ store// [Optional] Data store VUEX│ ├ ─ ─ the route// [Optional] Route│ ├ ─ ─ style// [Optional] Public style│ ├ ─ ─ App. Vue// [Mandatory] Root component│ └ ─ ─ main. (js) | ts// [Mandatory] Import file├ ─ ─ the public// [Required] Resources that are not compiled by WebPack│ ├ ─ ─ index. HTML// Mandatory│ └ ─ ─ logo. PNG// [Optional] Project logo├ ─ ─ the config// [Optional] Configure the directory├ ─ ─ the mock// [Optional] Mock data├ ─ ─ the test// [Optional] Test code├ ─ ─ the docs// [Optional] Document│ ─ ─ gitignore// [Mandatory] Git ignores the file│ ─ ─ editorconfig// [Mandatory] Compiler configuration│ ─ ─ npmignore// [Optional] If the package is NPM, this parameter is mandatory│ ─ ─ jsconfig. Json// [optional] used for vscode configuration├ ─ ─ the README, md// mandatory├ ─ ─ package. Json// [required] Everyone understands└ ─ ─...// [Optional] Configure some tools, such as babel.config.js, etc
Copy the code

Components, views Specific function division

Components write only public components, and the components that come with the page are written in views

└ ─ ─ the SRC ├ ─ ─ views │ └ ─ ─ home │ ├ ─ ─ index. The vue │ ├ ─ ─ Banner. Vue │ └ ─ ─ Card. The vue ├ ─ ─ components │ ├ ─ ─ Swiper. Vue │ └ ─ ─ Button. The vue ├ ─ ─ store// For large projects, it is recommended to split management by business module│ ├ ─ ─ index. Js │ ├ ─ ─ home. Js │ └ ─ ─ mime. Js ├ ─ ─ the route// For large projects, it is recommended to split management by business module│ ├ ─ ─ index. Js │ ├ ─ ─ home. Js │ └ ─ ─ mime. Js └ ─ ─ assets// Reuse common assets in the top-level assets file to avoid duplication of definition
Copy the code

Monitoring specification

Monitoring includes performance monitoring, exception monitoring, and service burying points. This section describes performance monitoring and exception monitoring specifications

Performance monitoring specification

All mobile end-oriented projects for C-side users must have access to performance monitoring

Project access

Performance monitoring and buried points are unified using the rotating performance SDK, using scaffolding initialization projects that will be plugged in by default

Performance check

You can browse the front-end performance platform to see the performance data you need

Performance warning rule

  • The frequency of warnings is once a day
  • Line of
    • The project first screen time is lower than1.5 sor1.5 sOpen rate is lower than60%
    • The first screen time is lower than that1.5 s, the calculated 1-day average
  • Warning way
    • Every day at 11 am, via the enterprise wechat
  • Whitelist mechanism to filter out items that do not need to be reported

Anomaly monitoring specification

Around the front-end error monitoring system based on Sentry, all projects must be connected to the exception monitoring.

Adjustment of reporting strategy

Some of the problems you might encounter with Sentry are as follows:

  • Information collection is chaotic (all error information mixed together);
    • Locating problems is relatively slow;
    • Scope of impact assessment is difficult;
    • Error frequency cannot be counted;
  • Partial lack of monitoring (not comprehensive monitoring);
    • Applets lack monitoring;
    • The interface is not monitored.
    • 404 requests lack monitoring
  • Warning emails are too frequent (which can cause developer fatigue);

Take the initiative to report

Intrusion project, although the front-end actual work has been to the business non-intrusion as the research direction. However, in the actual business, it is necessary to occasionally invade the business to do some processing, and bring considerable benefits to the business. What we can do is to minimize the intrusion of business code, resulting in pollution. The following is our transformation strategy for the project:

The page transformation

The above solution not only effectively catches errors and distinguishes error levels, but also effectively prevents sub-component errors from affecting the entire page rendering, resulting in a white screen.

The interface to monitor

Why do you need to do interface monitoring?

  • Assist backend error monitoring and log troubleshooting to provide more effective information;
  • Monitor the abnormal status of interfaces and services, and find vulnerabilities in existing code, server, and product logic according to the abnormal status;
  • Strengthen front-end developers to pay attention to online problems, and pay attention to interface errors, better integrate into the business;

Multi-dimensional labels & error information & custom error grouping rules

Advantage:

  • Quickly locate the problem (within 1 minute) and quickly assess the scope of impact;
  • More information needed for problem analysis to help solve problems quickly;
  • Organize error list, view error frequency, optimize code, service, and product logic risk;

The process specification

Package management specification

This section covers the development and distribution specifications of common packages

Internal private server CNPM

When publishing the package, the source address of Registry needs to be changed to the source address of registry

NPM package version number rule

Major version. Minor version. Revision number

The rule for increasing the version number is as follows:

  • Major version number: considered incompatibleAPIModify,
  • Second version number: as a functional addition for backward compatibility,
  • Revision number: fixed as a problem with backward compatibility. The prior version number and version build information can be added to the major version number. Second version number. Revision number “is followed as an extension.

After the major version is upgraded, the minor version and revision need to be reset to 0. After the minor version is upgraded, the revised version needs to be reset to 0.

About the test version suffix naming:

  • Alpha: Initial private beta, potentially unstable, e.g. 1.0.0-alpha.1.
  • Beta: mid-stage, but new features will continue to be added.
  • Rc:Release CandidateRelease candidate.RC– there will be no new features in v1.0, the focus will be on debuggingbetaAfter version, before the official version

Semver: Semantic version

  • Fixed version: a string representing a particular version of the package, for example, 1.0.1, 1.2.1-beta.0
  • Range version: a representation of a version that satisfies a specific rule, such as 1.0.3-2.3.4, 1.x, ^0.2, >1.4

Semantic description

Use semantic characters: ~, >, <, =, > =, < =, -, | |, x, x, *

- '^2.11.' // Latest version of 2.x (major version locked)
- '~2.11.' // Latest 2.1.x version (major and minor version locked)- > '2.1'   // Later than version 2.1
- '1.0. 0 - 1.2. 0' // The latest version between the two versions (must have Spaces)
- '*'      // Latest version number
- '3.x'    // Corresponds to the latest version number of part X
Copy the code

NPM install Install ^ X.X.X by default, which is compatible with the latest version of a larger version

Here, the front end of the development of the core of the main specifications on the introduction of the end, for different types of projects will have different specifications, we can according to the actual situation of the business, the development of their own team specifications ~

Articles of this month

Next, we will release zhuan in the performance, multi-terminal SDK, mobile terminal and other infrastructure and technology related to the practice and thinking, welcome you to pay attention to the public account “Da Zhuan FE”, looking forward to more exchanges with you