✨✨ believe that some of the pursuit of code partners, from HTML, CSS, JS, to Git and so on, will try to standardize their own code. If you do more than your own front-end development, you’re sure to follow a set of code development specifications (whether they’re your own or those that are more common in the industry).

People are not saints, even if you are a self-disciplined partner, you will inevitably make mistakes, or accidentally forget to write code in some places. So what to do? If it is a small Team with a relatively complete process, there may be a code review, HMM! This is a very good habit to have to improve your code quality and reduce the number of errors and so on. However, if there are some basic errors such as code format, writing order and so on, should we put them in the review phase? In other words, there are many friends in the team. As a leader, can you review these mistakes?

Since there are requirements, there must be corresponding solutions!! These front-end code specification related content, if left to tools, it would save a lot of effort, and more accurate, more efficient, right? Speaking of which, what does a front-end code specification do? Take a look at the picture below:

🌟 🌟 git – hooks tools

To do a good job, he must sharpen his tools. The hooks function in Git allows you to do something before or after executing Git commands, and many of your code checks will be done before committing, before pushing, etc. Husky is a git hooks tool that allows us to use git hooks more easily.

  • The first step is to initialize git for your project (if it has not been initialized by Git)
# project root
git init
Copy the code
  • Install the Husky
# Install (partial install)
npm i husky -D
Copy the code
  • Configure husky in package.json file
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test"."pre-push": "npm test",}}}Copy the code

By configuring husky.hooks[‘pre-commit’], we will run the commands we defined here (such as code specification checks, etc.) every time we do git commit. Emphasize:

  1. Make sure that == git initializes the project == before installing husky dependencies (after installing husky it automatically adds many hook files to the.git/hooks/ file). This is why Git first and husky later.

  2. If you installed husky first, you can also remove the dependencies and re-install husky dependencies after git initialization (the simplest way to do this is to remove the node_modules folder -> git init -> Install project dependencies).

  3. Git /hooks/ husky hook files are automatically added to husky hook files by checking. Git /hooks/.

  1. huskySupport allgit-hooks, common ones are:
The name of the instructions Bypass method
pre-commit Hooks before commit – no – verify parameters
commit-msg A hook before commit or merge – no – verify parameters
post-commit Hook after commit
pre-push A hook before a push that can be used to prevent a push

Refer to the Git hook documentation for more hooks.

🌟🌟 Verifies only the current changes

As the saying goes, weak water three thousand only take a ladle to drinkCopy the code

From the above, we know that you can use Husky to perform various Lint operations at commit time (the details of lint operations will be explained later). So, what if we want to lint only for what we’re currently changing, instead of all lint each time? The reasons for this will be explained later.

Lint-staged can be used in conjunction with Husky to prestage only what is currently submitted into staging (i.e., git Add), such as ESLint checking for repairs, prettier prettier, etc. πŸ‘‡ see how to use it:

  • The installationlint-staged
cnpm i lint-staged -D
Copy the code
  • Modify thehuskyHook configuration for

For example, we configured the hook function commit to run Lint-staged commands before committing

"husky": {
    "hooks": {
      "pre-commit": "lint-staged"}},Copy the code
  • configurationlint-staged

Create a new configuration file in the root directory, or set it to package.json:

Create a configuration file (Mac) in the root directory
touch .lintstagedrc
Copy the code

Write configuration. For example, we will only have lint-staged JS files in the SRC folder where things have been changed. Here ESLint is configured to check and automatically fix some formats, and then add lint-staged files again. In the configuration file:

{
  "./src/*.js": [
    "eslint --fix"]}Copy the code

Here is the configuration, for all the JS files we are currently changing, execute the following command. The key of the configuration object is the configured file matching rule, and the value is an array of commands executed on the matched file. There is no need to add git add after “eslint –fix” because lint-stage automatically adds all changes to the staging area. Also can carry on some beautification operation. As an extension, if you need to target multiple file types at the same time, you can either add configuration items or directly:

{
  "./src/*.{js,jsx}": [
    "eslint --fix"."git add"]."./ SRC /*. Matching rules for other types of files": []}Copy the code

The biggest difference between Lint-staged episodes is that you only act on the files currently changed, not all of them, which can be a boon for older projects without specifications that require maintenance and introduction of ESLint, where otherwise formatting code for older projects would be a disaster.

Refer to lint-staged documentation for more information

🐒🐒Angular Git submission specification

With these basic skills in hand, we are ready to start front-end specification related Lint. Git workflows are out of the scope of this discussion. They are outside the scope of this lint tool and depend on how your team works.

If you want to limit the Git commit specification, you should specify the Git commit specification first. Otherwise, a lot of useless information will be submitted comments, which will make people crazy!! We recommend using Angular’s Git submission specification, which is relatively common in the industry. The related tools can meet some common requirements. This is relatively helpful for small teams with weak front-end infrastructure. Take a moment to introduce Angular’s Git submission specification:

  • The specification consists of three parts,Header, Body, Footer.

Header contains three parts, type is the current submission type (mandatory), scope is the scope of files involved in the current submission (optional), and subject is the description of the current submission.

(

):


  • Type Type Description
type instructions
feat The new function
fix Bug fix
docs Change only the documentation
style Formatting of code
refactor Refactoring (without feat and fix operations)
perf Performance optimization
test Add unit tests and modify current unit tests
build Project build scripts or externally dependent changes (Webpack, NPM, etc.)
ci CI/CD related files and script changes (Travis, Circle, BrowserStack, SauceLabs)
chore Make changes other than SRC /test (e.g. changes to various rc files in the root directory, etc.)
revert Version rollback
# Here's an example
git commit -am "Feat (TheNav): Complete navigation package"
Copy the code

🌟🌟 Auxiliary generationgit commitTools of information

With the submission specification, some people may not remember so many types and make it difficult to submit. Don’t worry, we have a solution so you can be lazy in peace.

Commitizen is a tool used to assist in generating git commit information specifications. The use effect is shown below:

Is not very Nice, the heart is not so a trace of ❀️ heart ❀️ feeling ~ ~ ~ come on, see if you use:

  • The installation
cnpm i commitizen -D
Copy the code
  • Configuration parameters (package.json)
{
  "scripts": {
    "commit": "git-cz"
  },
  "config": {
    "commitizen": {
        "path": "cz-conventional-changelog"}}},Copy the code

Config.mitizen. path config.mitizen. path config.mitizen. path config.mitizen. path config.Mitizen. path config.Mitizen. You can also install other adapters or customize the generation rules for Commitizen’s tip content (custom plug-in tools documentation).

  • Later usenpm run commitGit commit

🌟🌟 Verify that the COMMIT information complies with specifications

Git commit -am: “git commit -am” : “git run commit” : “git commit -am:” Commitlint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint = commitLint

  • The installation
cnpm i @commitlint/{config-conventional,cli} -D
Copy the code
  • Use with husky hooks
{
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"}}}Copy the code
  • The configuration file

Create a new commitlint.config.js file in the root directory:

module.exports = {
  extends: [
    '@commitlint/config-conventional']};Copy the code

This way, when we use the COMMIT feature, the commit information will be formally validated. Commits that do not conform to the Angular specification automatically fail. You can also customize some types, specific or see the document!!

🌟🌟 Automatically generates CHANGELOG

We can see that many libraries have change logs, which would be like a baby if they were written by hand. Do we wish there was a tool that could help us do that?

Git submission specifications can be generated automatically using Xconventional – Changelog – CLI if they are Angular based.

  • The installation
cnpm i conventional-changelog-cli -D
Copy the code
  • Configuration Script Command

We define a script command to generate changeLog, notice that it is regenerated each time before overwriting. You can also set it to append to the file each time

"scripts": {
    "version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"
},
Copy the code

For details, you can refer to the Convention-Changelog-CLI document. The final effect is as follows:

🌟🌟 Verify the CSS specifications

Git submission specification Lint for local development Let’s take a look at some of the specifications for code development. So first, let’s start with the CSS specification Lint. Just like Lint with JS, CSS also needs to be checked for errors such as spacing and semicolons; Disallow invalid color values. Set the maximum nesting depth ah; Specify indent, newline ah; Property values have to be abbreviated and so on.

Stylelint is a Lint tool for constraining CSS specifications. Can cooperate with CSS/less/SCSS/sass/stylus together, such as post – support CSS parser in theory, can be compatible with use. Parsing syntax is automatically derived based on the file type, but you can also specify the language type to parse. πŸ‘‡ to see how to use it:

  • Install the Stylelint and rule configuration collection
cnpm i stylelint stylelint-config-standard -D
Copy the code

Stylelint-config-standard is a set of code rules for Stylelint, which contains commonly used CSS specification constraints. It is the official recommended set of basic rules. The stylelint-config-standard specification inherits the stylelint-config-Recommended specification set, with some rules that are turned on and off.

  • The configuration file

After the dependencies are installed, we need to configure them in the project. You can create any of the following files in the root directory:

/** *.stylelintrc.json or.stylelintrc * use the standard JSON format * note that json files are not allowed to write annotations
{
    "extends": "stylelint-config-standard"
}

/** *.stylelintrc.js or stylelint.config.js * note that the export mode is CMD */
module.exports = {
  plugins: [].extends: 'stylelint-config-standard'.rules: {}}// There are no more ways to use these
// I prefer js to json, the syntax is more comfortable
Copy the code

The extends field is the collection of Stylelint rules that use our installation. Of course, we don’t have to use these set rules, we can define our own. Extends can also be an array (it can be just one or a string), and the latter can be merged into the former, which is the same rule that overwrites the former. Each entry in the array can be either a downloaded package or a local file path (any path that complies with the require.resolve() algorithm resolution rules).

  • Description of other fields in the configuration file

Rules defines a collection of rules, which is an object with a key as the rule name and a value as the rule configuration:

/ / such as:
module.exports = {
  rules: {
    "block-no-empty": null.// For example, define the indentation rule
    'indentation': [
      // 2 Spaces
      2,
      {
        / / receive XXX
        "except": ["block"].// Error message
        "message": "Please use 2 spaces for indentation.".// Rule level, either warning or error
        "severity": "warning"}}}]Copy the code
  • The built-in rules

Stylelint has 170 rules (document addresses) built-in by default, but none of them are turned on by default (you need to specify them yourself, including some recommended libraries, which are also listed). Here are some common rules:

The rules instructions
color-no-invalid-hex Disallow invalid hexadecimal colors
unit-no-unknown Do not use unknown units
property-no-unknown Disable unknown attributes
keyframe-declaration-no-important Not allowed in keyFrame! important
declaration-block-no-duplicate-properties Disallow the use of duplicate attributes in a declaration block
block-no-empty Prohibit empty block
selector-pseudo-class-no-unknown Disallow unknown pseudo-class selectors
selector-pseudo-element-no-unknown Disallow unknown pseudo-element selectors
selector-type-no-unknown Disable unknown type selectors
comment-no-empty Disable empty comments
no-extra-semicolons Do not use extra semicolons
no-invalid-double-slash-comments Ban / /… The CSS does not support double slash comments
color-named Disallow named colors
color-no-hex Do not use hexadecimal colors
length-zero-no-unit Units of length zero are not allowed (auto repair)
color-hex-case Specify lowercase or uppercase for hexadecimal colors (auto-fixable)
shorthand-property-no-redundant-values Property values that can be abbreviated need to be abbreviated
max-nesting-depth Maximum nesting depth
number-leading-zero The leading 0 when the number is less than 1
number-no-trailing-zeros No trailing 0
unit-case Specify lowercase or uppercase for units (autofix)
string-quotes String specifies single or double quotation marks
value-keyword-case Specifies the keyword value as lowercase or uppercase
property-case Specify lowercase or uppercase for the attribute
comment-whitespace-inside Require or disallow Spaces inside comment tags (autofix)
comment-empty-line-before Require or disallow blank lines before comments (autofix)
indentation Specify indentation (auto repair)
max-empty-lines Limit the number of adjacent blank lines (auto repair)
max-line-length Limit the length of a line
no-eol-whitespace Disallow line end Spaces (autofix)
at-rule-name-newline-after A newline character is required after the rule name
  • Stylelint performs ignore check

Ignore all rules:

/* stylelint-disable */
a {}
/* stylelint-enable */
Copy the code

Ignore specific rules:

/* stylelint-disable selector-no-id, declaration-no-important */
#id {
  color: pink ! important;
}
/* stylelint-enable selector-no-id, declaration-no-important */
Copy the code

Ignore a line:

#id { /* stylelint-disable-line */
  color: pink ! important; /* stylelint-disable-line declaration-no-important */
}
Copy the code

Ignore the next line:

#id {
  /* stylelint-disable-next-line declaration-no-important */
  color: pink ! important;
}
Copy the code

Support stacking:

/* stylelint-disable */
/* stylelint-enable foo */
/* stylelint-disable foo */
/* stylelint-enable */
/* stylelint-disable foo, bar */
/* stylelint-disable baz */
/* stylelint-enable baz, bar */
/* stylelint-enable foo */
Copy the code

Stylelint Document address

Stylelint-config-standard Document address

Stylelint-config-recommended document address

  • Stylelint Resource set Recommendation

For more stylelint recommendations, see the Stylelint Resource Collection address

🌟🌟 Verify the sequence of CSS properties

In fact, the junior partner with CSS development experience, in the order of writing CSS basically all have so a set of methodology, such as many will common-sense write layout will affect the element attribute in the front, like the position | display, Then the wide high inner and outer margin width | height | padding | margin. In fact, in addition to CSS attributes, there are more such as variables, preprocessor mixed and so on, in the CSS specification, we can put these attributes in order can also be checked and automatically repair CSS.

The stylelint-Order plug-in lets you set the order of the CSS properties, such as what should be placed first and what should be placed last. Here’s how to use it in a project:

  • Installation method
# Prerequisite if stylelint is installed
cnpm i stylelint-order -D
Copy the code
  • Configuration in the stylelint configuration file
module.exports = {
  extends: [
    // CSS standard configuration
    'stylelint-config-standard',].// Use the stylelint-Order through the plug-in
  plugins: ['stylelint-order'].rules: {
    'order/order': [
      'custom-properties'.// eg: --property: 10px;
      'dollar-variables'.// eg: $variable
      'at-variables'.// eg: @someVar
      'declarations'.// CSS properties, display: flex
      'rules'.// Nested attributes, eg:.head {.top: {... }}, where. Top {} is a set nested in. Head
      // 'at-rules', // contains nested attributes
      // 'less mixins' // less mixins, eg:.mixin()].'order/properties-order': [
        'width'.'height'
        // ...]}}Copy the code

Note that all rules plugins specify the plugins to be modified in the object properties, such as order, then order/order and order/properties-orde. As shown above, we can configure a large set of rules in order/order, such as custom-properties type content in front, CSS properties collection in the back, and so on. This is the big direction. Order /properties-order is the order in which CSS properties are placed for specific configuration. For example, width is placed first, followed by height, etc.

The rules for setting order/properties-order are documented. Github also has a few configured solutions (though not many stars), such as these resources mentioned by the authorities (I have a screenshot here, you can check it out in the documentation) :

🌟🌟 Repair the CSS sequential integration solution

Stylelint-config-recess – Order is a layer of encapsulation of stylelint-Order, which is relatively simple to use. The relevant order configuration has been written.

  • Installation method
cnpm i stylelint-config-recess-order -D
Copy the code
  • Because the stylelint-Order is already built into the plug-in, there is no need to repeat the installation.
// The usage mode
module.exports = {
  extends: [
    'stylelint-config-standard'.'stylelint-config-recess-order']}Copy the code
  • Its list of rules:
module.exports = {
  plugins: ['stylelint-order'].rules: {
    'order/properties-order': [{
      // Must be first.
      properties: ['all'],}, {// Position.
      properties: ['position'.'top'.'right'.'bottom'.'left'.'z-index',]}, {// Display mode.
      properties: ['box-sizing'.'display',]}, {// Flexible boxes.
      properties: ['flex'.'flex-basis'.'flex-direction'.'flex-flow'.'flex-grow'.'flex-shrink'.'flex-wrap',]}, {// Grid layout.
      properties: ['grid'.'grid-area'.'grid-template'.'grid-template-areas'.'grid-template-rows'.'grid-template-columns'.'grid-row'.'grid-row-start'.'grid-row-end'.'grid-column'.'grid-column-start'.'grid-column-end'.'grid-auto-rows'.'grid-auto-columns'.'grid-auto-flow'.'grid-gap'.'grid-row-gap'.'grid-column-gap',]}, {// Align.
      properties: ['align-content'.'align-items'.'align-self'],}, {// Justify.
      properties: ['justify-content'.'justify-items'.'justify-self',]}, {// Order.
      properties: ['order'],}, {// Box model.
      properties: ['float'.'width'.'min-width'.'max-width'.'height'.'min-height'.'max-height'.'padding'.'padding-top'.'padding-right'.'padding-bottom'.'padding-left'.'margin'.'margin-top'.'margin-right'.'margin-bottom'.'margin-left'.'overflow'.'overflow-x'.'overflow-y'.'-webkit-overflow-scrolling'.'-ms-overflow-x'.'-ms-overflow-y'.'-ms-overflow-style'.'clip'.'clear',]}, {// Typography.
      properties: ['font'.'font-family'.'font-size'.'font-style'.'font-weight'.'font-variant'.'font-size-adjust'.'font-stretch'.'font-effect'.'font-emphasize'.'font-emphasize-position'.'font-emphasize-style'.'-webkit-font-smoothing'.'-moz-osx-font-smoothing'.'font-smooth'.'hyphens'.'line-height'.'color'.'text-align'.'text-align-last'.'text-emphasis'.'text-emphasis-color'.'text-emphasis-style'.'text-emphasis-position'.'text-decoration'.'text-indent'.'text-justify'.'text-outline'.'-ms-text-overflow'.'text-overflow'.'text-overflow-ellipsis'.'text-overflow-mode'.'text-shadow'.'text-transform'.'text-wrap'.'-webkit-text-size-adjust'.'-ms-text-size-adjust'.'letter-spacing'.'word-break'.'word-spacing'.'word-wrap'.// Legacy name for `overflow-wrap`
      'overflow-wrap'.'tab-size'.'white-space'.'vertical-align'.'list-style'.'list-style-position'.'list-style-type'.'list-style-image',]}, {// Accessibility & Interactions.
      properties: ['pointer-events'.'-ms-touch-action'.'touch-action'.'cursor'.'visibility'.'zoom'.'table-layout'.'empty-cells'.'caption-side'.'border-spacing'.'border-collapse'.'content'.'quotes'.'counter-reset'.'counter-increment'.'resize'.'user-select'.'nav-index'.'nav-up'.'nav-right'.'nav-down'.'nav-left',]}, {// Background & Borders.
      properties: ['background'.'background-color'.'background-image'."-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient".'filter:progid:DXImageTransform.Microsoft.gradient'.'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader'.'filter'.'background-repeat'.'background-attachment'.'background-position'.'background-position-x'.'background-position-y'.'background-clip'.'background-origin'.'background-size'.'background-blend-mode'.'isolation'.'border'.'border-color'.'border-style'.'border-width'.'border-top'.'border-top-color'.'border-top-style'.'border-top-width'.'border-right'.'border-right-color'.'border-right-style'.'border-right-width'.'border-bottom'.'border-bottom-color'.'border-bottom-style'.'border-bottom-width'.'border-left'.'border-left-color'.'border-left-style'.'border-left-width'.'border-radius'.'border-top-left-radius'.'border-top-right-radius'.'border-bottom-right-radius'.'border-bottom-left-radius'.'border-image'.'border-image-source'.'border-image-slice'.'border-image-width'.'border-image-outset'.'border-image-repeat'.'outline'.'outline-width'.'outline-style'.'outline-color'.'outline-offset'.'box-shadow'.'mix-blend-mode'.'filter:progid:DXImageTransform.Microsoft.Alpha(Opacity'."-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha".'opacity'.'-ms-interpolation-mode',]}, {// SVG Presentation Attributes.
      properties: ['alignment-baseline'.'baseline-shift'.'dominant-baseline'.'text-anchor'.'word-spacing'.'writing-mode'.'fill'.'fill-opacity'.'fill-rule'.'stroke'.'stroke-dasharray'.'stroke-dashoffset'.'stroke-linecap'.'stroke-linejoin'.'stroke-miterlimit'.'stroke-opacity'.'stroke-width'.'color-interpolation'.'color-interpolation-filters'.'color-profile'.'color-rendering'.'flood-color'.'flood-opacity'.'image-rendering'.'lighting-color'.'marker-start'.'marker-mid'.'marker-end'.'mask'.'shape-rendering'.'stop-color'.'stop-opacity',]}, {// Transitions & Animation.
      properties: ['transition'.'transition-delay'.'transition-timing-function'.'transition-duration'.'transition-property'.'transform'.'transform-origin'.'animation'.'animation-name'.'animation-duration'.'animation-play-state'.'animation-timing-function'.'animation-delay'.'animation-iteration-count'.'animation-direction',],},],},}Copy the code

Note that if the property is not defined in the list above, it can be placed anywhere in any property, but specific locations can be set (for example, undefined properties can only be placed in front of, after, and so on).

Stylelint-order reads the fix option for stylelint by default, or if enabled, it is automatically fixed. The stylelint-Order can also be customized.

  • Used in conjunction with Husky
// package.json husky configuration "husky": {"hooks": {"pre-commit": "Lint - staged"}} / /. Lintstagedrc configuration {". / SRC / *. {less CSS, HTML, HTM, vue} ": [" stylelint - fix"]}Copy the code
  • Configured in the vue

Here’s how to configure a modern VUE project. React is similar to webpack configuration. Install the webPack plugin first:

# Plugin for stylelint and its Webpack
cnpm i -D stylelint stylelint-webpack-plugin

Configure specifications and order configurations
cnpm i stylelint-config-standard stylelint-config-recess-order -D

Copy the code

To use, configure in webpack.config.js:

const StyleLintPlugin = require('stylelint-webpack-plugin');
module.exports = {
  / /... Other options
  plugins: [
    new StyleLintPlugin({
      // Specify the file to test
      files: ['**/*.{vue,htm,html,css,sss,less,scss,sass}'].// Start automatic repair
      fix: true.cache: true // Enable caching}})]/ / cli4 writing
/** * Add stylelint plug-in */
config.plugin('stylelint')
  .use(StyleLintPlugin, [{
    // Specify the file to test
    files: ['./src/**/*.{vue,css,less}'].// Start automatic repair
    fix: true.cache: true.// Enable caching
  }])
Copy the code

Local configuration file:

/ /. Stylelintrc. Js file
module.exports = {
  extends: [
    'stylelint-config-standard'.'stylelint-config-recess-order'],}Copy the code
parameter instructions
files Specifies which files lint will be used for
fix Auto repair
cache Enable the cache function of stylelint for a great speed increase

How to configure the documentation for stylelint in the VUE project

🌟🌟 Verify BEM naming conventions

Basically CSS naming conventions, the industry has a lot of suit and BEM, if you are not clear about these naming conventions can learn first.

We can check CSS naming conventions with postcss-bem-linter, which supports stylelint-selector-bem-pattern in styelInt. Postcss-bem-linter postcss-bem-linter

  • Install postcss – bem – linter
# postcss-bem-linter installation
No installation is required if used as a styLint plugin
cnpm i postcss-bem-linter -D
Copy the code
  • Install stylelint – the selector – bem – the pattern
# If you are using bemLint in stylelint, simply install the plug-in
cnpm i stylelint-selector-bem-pattern -D
Copy the code
  • The stylelint-selector-bem-pattern is used in stylelInt
module.exports = {
  plugins: [
    'stylelint-selector-bem-pattern'].rules: {
    'plugin/selector-bem-pattern': {
      // Select Preset Patterns, which support both suit and BEM, and Preset specification is the default;
      Either way, you need to specify it manually because the plug-in does not specify it by default for the source plug-in
      'preset': 'bem'./** * a custom pattern rule specifies a combinatorial selector check rule, which specifies the class name rule */ supports regular strings, functions that return the regular, objects that contain two optional arguments, etc
      componentSelectors: {
        // Only the initial selector rule
        initial: '^\\.{componentName}(? :__[-a-z]+)? (? :--[a-z]+)? $'.// can be understood as the rule of the selector inside the outer layer,
        // If not specified, the same rule as initial,
        // Note that there is one less question mark than above,
        // The inner layer should not have only componentName as selector
        combined: '^\\.{componentName}(? :__[-a-z]+)(? :--[a-z]+)? $'
      },
      "utilitySelectors": "^\\.u-[a-z]+$".ignoreSelectors: ['^\\.el-'.'/deep/'.'> > >'.'^\\.icon-'].ignoreCustomProperties: [],}}}Copy the code

Rules [‘plugin/selector-bem-pattern] is used to configure parameters. The stylelint-Selector -bem-pattern is only the encapsulation of the postCSs-bem-Linter, so the essence is to configure the postCSs-bem-Linter parameters. Stylelint-selector -bem-pattern has no parameters. But one thing to note: The default rule for postCSs-bem-linter is suit, but the stylelint-selector-bem-pattern does not give postCSs-bem-linter a default rule, so even if suit is used, it needs to be specified manually, as preset parameter above

🌟 🌟 explanation postcss – bem – linter

The postcss-bem-Linter document looks a bit awkward at first, and can be a bit awkward for unfamiliar users. So here, I will introduce some basic common will be used again, to help partners quickly understand and use:

  • There are two modes: default and weak

The default mode is default, that is, selectors and custom properties must comply with lint rules; In weak mode, only the outermost layer must conform to Lint rules. Nested selectors and custom attributes do not need to conform to lint rules. Otherwise, you can specify the weak mode in the file through comments:

/** @define app; weak */
.app--active {
    color: #f00;
}
Copy the code
  • Defining pattern

Suit and BEM are supported and follow their corresponding naming conventions. For details, you can refer to their specification documents: suit document and BEM document

// Use in stylelint:
rules: {
    'plugin/selector-bem-pattern': {
         preset: 'bem'}}Copy the code
  • Lint rules that define component names

ComponentName can be a regular expression function that returns RegExp() :

rules: {
    'plugin/selector-bem-pattern': {
        preset: 'bem',
        componentName: '[a-z]+',
    }
}   
Copy the code
  • Component names are defined through component annotations within components

Define component names, such as app:

/** @define app */
Copy the code

Define Utilities, the name is arbitrary

If utilities is defined by comments in a component (or other file), the selector must meet the rules in the configuration parameters. /** @define Utilities */ For configuration rules, all tool selectors must start with a u-letter. { 'plugin/selector-bem-pattern': { preset: 'bem', utilitySelectors: '^\\.u-[a-z]+$', } }Copy the code

Can be combined:

/** @define app */

/** @define app2 */

/** @define app3 */

/** @define utilities */
Copy the code
  • Specifies the composition rule for the selector
/** * class names support regular strings, functions that return regular strings, objects that contain 2 options, etc. */ componentSelectors {// Initial: '^\\.{componentName}(? :__[-a-z]+)? (? :--[a-z]+)? $', // yi combined: '^\\.{componentName}(? :__[-a-z]+)(? :--[a-z]+)? $'},Copy the code
  • Ignore some selector checks
/** * You can configure the selectors to be ignored directly in the configuration parameters, * for example, when we overwrite the third-party styles in the component, we will write the third-party styles ** common, such as. El-xxxx, which is ignored in the configuration. {// 'max-nesting-depth': 4, 'plugin/ selector-pattern ': {preset: 'bem', // Preset: [' ^ \ \. El - ', '/ deep/',' > > > ', '^ \ \. Icon -'], / / ignore custom attributes related validation ignoreCustomProperties: [].}}Copy the code

Notice here, we can passignoreSelectorsIgnore what we might use in our daily developmentDeep and iconInterference with lint tools by selectors, etc.

  • CSS ignores option validation on the next line

Note that only the selectors on the next line are ignored:

/* postcss-bem-linter: ignore */
.xxx-ssssss {
    border-right: 0;
}
Copy the code
  • Finally put a basic stylelint configuration
module.exports = {
  extends: [
    // Standard collection, inherited from stylelint-config-Recommend
    'stylelint-config-standard'.// Built-in stylelint-Order for sorting
    'stylelint-config-recess-order'].plugins: [
    'stylelint-selector-bem-pattern'].rules: {
    'plugin/selector-bem-pattern': {
      /** * Select Preset Patterns, which support both suit and BEM, and Preset specification is the default; Either way, you need to specify this manually because the plug-in does not specify */ by default for the source plug-in
      preset: 'bem'.// Know the check rules for component names
      componentName: '[a-z]+'./** * specifies a combinative selector check rule, which specifies the class name rule * to support the regular string, the function that returns the regular, the object that contains two optional arguments, etc. */
      componentSelectors: {
        // Only the initial selector rule
        initial: '^\\.{componentName}(? :__[-a-z]+)? (? :--[a-z]+)? $'.// Can be interpreted as outer yi
        combined: '^\\.{componentName}(? :__[-a-z]+)(? :--[a-z]+)? $'
      },
      utilitySelectors: '^\\.u-[a-z]+$'.ignoreSelectors: ['^\\.el-'.'/deep/'.'> > >'.'^\\.icon-'].ignoreCustomProperties: [],}}}Copy the code

🌟🌟 Verifies THE HTML code specification

Now that we’ve covered the style section, let’s look at how HTML constrains. Htmlhint, a tool for the HTML code specification of Lint, is explained here.

  • The installation
cnpm i htmlhint -D

If used in webpack, only its loader will be installed
cnpm i htmlhint-loader -D
Copy the code
  • configuration

Htmlhintrc: create a configuration file in the root directory. Htmlhintrc:

{
  "tagname-lowercase": false,
  "attr-lowercase": true,
  "attr-value-double-quotes": true,
  "alt-require": true,
  "tag-pair": true,
  "src-not-empty": true,
  "id-class-ad-disabled": true,
  "id-unique": true,
  "inline-style-disabled": true
}
Copy the code
  • Configuration instructions

Configuration is relatively few, also about 30, the following common:

configuration instructions type
tagname-lowercase HTML tag lowercase boolean
attr-lowercase HTML attributes lowercase boolean
attr-value-double-quotes Attribute values must have double quotes boolean
alt-require Elements such as IMG must have an Alt attribute boolean
tag-pair Labels must match correctly boolean
src-not-empty The SRC attribute cannot be empty boolean
id-class-ad-disabled The ID or class cannot use AD boolean
id-unique Id must be unique boolean
inline-style-disabled Inline styles are not allowed boolean
  • Configuring Lint-staged use
// .lintstagedrc.js
module.exports = {
  './src/**/*.{vue,ts,tsx,js,jsx}': [
    'eslint --fix'
  ],
  './src/**/*.{vue,css,less}': [
    'stylelint --fix'
  ],
  './src/**/*.vue': [
    'htmlhint --config ./.htmlhintrc'
  ],
}
Copy the code

Note that the htmlhint-loader is only used for vue files. Currently it is tested for conflicts with webpack-html-loader, so the index. HTML template is discarded.

  • Used in the vue

To configure in the vue.config.js file:

config.module
  .rule('html')
  .enforce('pre')
  .test(/\.(vue)(\? . *)? $/)
    .exclude
    .add(path.join(__dirname, 'node_modules'))
    .end()
  .use('htmlhint-loader')
    .loader('htmlhint-loader')
    .tap(() = > ({ configFile: './.htmlhintrc' }))
    .end()
Copy the code

🌟🌟 Verify THE JS specifications

ESLint is the js code specification for Lint and style checker, which is basically a standard setup for cli projects, and I’m sure you’re all familiar with it. JSLint, JSHint, JSLint, JSHint, JSLint, JSHint Prettier is a code beautification tool that can be used in conjunction with ESLint, where a separate library overwrites conflicting rules for prettier. More than that, I personally think ESLint is probably adequate.

  • The installation
cnpm i eslint -D
Copy the code
  • The configuration file

The root directory for creating.eslintrc or.eslintrc.js files

// .eslintrc.js
module.exports = {
    rules: {
        semi: [""."always"].quotes: ["error"."double"]}}Copy the code

All supported profile types, as shown below:

  • rules
{
    "rules": {
        "semi": ["error", "always"],
        "quotes": ["error", "double"]
    }
}
Copy the code

Array is the key rule name, the first level for rules (closed: 0 | off, warning: 1 | warn, error: 2 | errors)

  • Close the rule with comments
// Turn off the specified rule for a certain section of code
/* eslint-disable no-alert, no-console */
alert('foo');
console.log('bar');
/* eslint-enable no-alert, no-console */

// Close the entire file rule
// Add the comment at the top of the file
/* eslint-disable */

// Ignore the rule for the specified line
alert('foo'); // eslint-disable-line
// eslint-disable-next-line
alert('foo');
/* eslint-disable-next-line */
alert('foo');
alert('foo'); /* eslint-disable-line */
Copy the code
  • plugin

The plugin configuration can omit the package name prefix eslint-plugin-

{"plugins": ["react", // equivalent to "eslint-plugin-react"]}Copy the code
  • extends

  • Override Settings

You can respecify some configuration parameters for the specified files, such as the files to be ignored. Files that need to be ignored can also be specified using.eslintignore.

{
  "overrides": [{"files": ["bin/*.js"."lib/*.js"]."excludedFiles": "*.test.js"."rules": {
        "quotes": ["error"."single"}}]}Copy the code
  • How to use ESLint in VUE
// With webpack, in vue.config.js

module.exports = {
  publicPath: process.env.PUBLIC_PATH,
  chainWebpack: config= > {
    config.module
      .rule('eslint')
      .use('eslint-loader')
      .loader('eslint-loader')
      .tap(options= > {
        // Make ESLint automatically fix code when saving
        options.fix = true
        // Enable caching
        options.cache = true
        return options
      }).end()
  }
}
Copy the code

For more esLint configurations in WebPack, see the esLint-Loader documentation

🌟 🌟 explanation eslint – plugin – vue

Vue-cli4 initializes part of the JS project esLint configuration:

The partial configuration of THE TS project ESLint initialized by VUE-CLI4:

The ts and JS versions of the project differ by adding a set of typescript/ Recommend rules

Plugin :vue/essential eslint-plugin-vue is A basic error for vue2+ in eslint-plugin-vue. Lint (i.e. priority level A) can be added if other rule sets need to be enabled:

{
  extends: [
      'plugin:vue/essential',
      '@vue/airbnb',
      '@vue/typescript/recommended',
      // Enable the verification whose priority is B
      'plugin:vue/strongly-recommended',
      // Enable the verification whose priority is C
      'plugin:vue/strongly-recommended'
  ],
  rules: {
      // Note that I personally don't like the > of HTML tags to wrap on multiple lines
      // So turn this feature off
      "vue/html-closing-bracket-newline": ["error", {
        "singleline": "never"."multiline": "never"}]}}Copy the code

Note that versions of eslint-plugin-vue are currently installed on the CLI as stable version 6.2.2, newer versions as well as 7.0.0-beta.1(currently 2020-08-12), so some of the new lint documentation, Is based on the new version (for example, custom event names must be hyphenated instead of small hump, etc.), and the document is also the new version of the document, which is a little bit important.

There are also rules that do not fall into these levels and can be enabled or configured on their own

Eslint plugin – vue document

🌟🌟JSDoc code comment specification

Git, HTML, CSS, JS, and Vue specifications are mentioned above, but there is also a specification for annotations. Good annotations can reduce the cost of understanding code and aid in automatic documentation. πŸ‘‡ We will introduce the comment specification of JSDoc below:

JSDoc defines a series of block-level tags to describe the content of various comments, written basically as follows:

/** * The content of your comment **@param { number } id- User ID *@returns { object } Return the found user data */
Copy the code

Here’s a look at some of the common tags and what they do:

  • Abstract abstract class or method
  • @class describes a class or constructor that needs to be called by new, alias @constructor
  • @extends describes which parent class it inherits from
  • Override describes methods that override a parent class
  • @callback describes a callback function
  • @description defines the description, which can be omitted if placed in the first line
/**
 * δΊΊ
 * @class
 * @extends Animal* /
class Person extends Animal {
  private name: string;
  constructor(name: string) {
    super(name);
    this.name = name;
  }
  /** ** state your name *@param { Person~sayCallback } cb- The callback function of the say method */
  say(cb) {
    console.log(this.name);
    typeof cb === 'function' && cb(this); }}/** * This callback is displayed as part of the Person class *@callback Person~sayCallback
 * @param {this} Cb Person instance */
Copy the code
  • @constant describes a constant
  • @type describes a type, which can be used in combination with @param, @constant, and so on
  • @default defines the default value. If it is a simple value, you can let JSDoc get it by writing @default, or you can define the default value yourself
 / * * *@constant
  * @type { string }
  * @default* /
 const COLORT = '#f00'
Copy the code
  • @ enum enumeration
  • @readonly
/** * enumerate move state *@enum {number}
  * @readonly* /
enum MoveStatus {
  up = 1,
  right,
  bottom,
  left
}
Copy the code
  • @example Describes a usage example
/** * Format the number unit, if the number is automatically changed to a number plus a px end **@example* formatUiSize(20) // Returns '20px' *@example* formatUiSize('20px') // Returns '20px' *@param {number | string} val- The unit to be formatted *@returns {string} Returns the formatted unit */
export const formatUiSize = (val: string | number): string | number= > (typeof val === 'number'
  ? `${val}px`
  : val);

Copy the code
  • @function and @method represent a function or method
  • @global describes a global variable
  • @mixin describes a mixin object
  • @Mixes with other objects
  • @param Description of the parameters of a function, including the parameter name, parameter data type, and description
/ * * *@param {string} somebody - Somebody's name.
 */
function sayHello(somebody) {
    alert('Hello ' + somebody);
}

// If the argument is an object with many attribute arguments
/**
 * Assign the project to an employee.
 * @param {Object} employee - The employee who is responsible for the project.
 * @param {string} employee.name - The name of the employee.
 * @param {string} employee.department - The employee's department.
 */
Project.prototype.assign = function(employee) {
    // ...
};


/**
 * Assign the project to a list of employees.
 * @param {Object[]} employees - The employees who are responsible for the project.
 * @param {string} employees[].name - The name of an employee.
 * @param {string} employees[].department - The employee's department.
 */
Project.prototype.assign = function(employees) {
    // ...
};


// Optional parameters and default values
/ * * *@param {string} [somebody=John Doe] - Somebody's name.
 */
function sayHello(somebody) {
    if(! somebody) { somebody ='John Doe';
    }
    alert('Hello ' + somebody);
}
Copy the code
  • @returns describes a return value. The usage is similar to @param
  • @throws Describes a function that may throw an error
/ * * *@throws Will throw an error if the argument is null.
 */
function bar(x) {}
Copy the code

🌟🌟 Verify that comments are normal

Jsdoc type comments are checked for compliance with the specification using the eslint-plugin-jsdoc plug-in.

  • The basic use
module.exports = {
    plugins: [
        'jsdoc'].extends: [
        // 'plugin:vue/essential',
        // '@vue/airbnb',
        // '@vue/typescript/recommended',
        
        // Start all recommended rules
        'plugin:jsdoc/recommended',].rules: {
        // Detect invalid padding blocks
        'jsdoc/check-indentation': 'warn',}}Copy the code
  • All inspection rules
"rules": {
    // * must be aligned to the standard
    "jsdoc/check-alignment": 1.// Recommended
    // Check whether the js code in example conforms to esLint rules
    "jsdoc/check-examples": 1.// Detect invalid padding blocks
    "jsdoc/check-indentation": 1
    // Check whether the param name matches the parameter name in the function
    "jsdoc/check-param-names": 1.// Recommended
    "jsdoc/check-syntax": 1.// Check whether the block tag name is correct, for example, @paramsss is wrong
    "jsdoc/check-tag-names": 1.// Recommended
    // Check whether the parameter type is correct, such as {object}, can automatically repair case
    "jsdoc/check-types": 1.// Recommended
    "jsdoc/implements-on-classes": 1.// Recommended
    // Restrict what can be described with regular expressions
    // For example, limit the use of English, capital letters, etc
    "jsdoc/match-description": 1.// Enforces a blank line after the description
    "jsdoc/newline-after-description": 1.// Recommended
    "jsdoc/no-types": 1.// Undefined parameter types are not allowed, such as {STRRRRR}
    "jsdoc/no-undefined-types": 1.// Recommended
    // All functions are required to have descriptions
    "jsdoc/require-description": 1.// Complete markup is required, such as @description, instead of a literal description
    "jsdoc/require-description-complete-sentence": 1.// all functions must have example
    "jsdoc/require-example": 1."jsdoc/require-hyphen-before-param-description": 1.// Check for Jsdoc comments on class declarations and functions
    "jsdoc/require-jsdoc": 1.// Recommended
    // write all arguments to param
    "jsdoc/require-param": 1.// Recommended
    "jsdoc/require-param-description": 1.// Recommended
    // Require each @param tag to have a description
    "jsdoc/require-param-name": 1.// Recommended
    // Require each @param tag to have a type parameter
    "jsdoc/require-param-type": 1.// Recommended
    "jsdoc/require-returns": 1.// Recommended
    // When @returns is used, the function is checked to see if there is a qualified return value
    "jsdoc/require-returns-check": 1.// Recommended
    // @returns must have a description
    "jsdoc/require-returns-description": 1.// Recommended
    // @returns must have a return type argument
    "jsdoc/require-returns-type": 1.// Recommended
    // Verify the validity of the type
    "jsdoc/valid-types": 1 // Recommended
}
Copy the code

Note that ‘plugin:jsdoc/recommended’ in the eslintrc.js configuration file automatically opens all recommended rules in the above Lint rule.

Eslint-plugin-jsdoc document address

The last

One hundred feet pole head, day further, I am your old friend Leng hammer!! More content recommendation, remember to pay attention to, like not lost oh ~ ~ ~

  • Full guide to the development of front-end scaffolding drainage pit [front-end efficiency must be dry goods]
  • Vue + TS +class+ annotation style development pit full guide
  • Get started with the Egg.js+Nunjucks template engine in 5 minutes to quickly develop SEO-friendly projects
  • The core content of koA2 full stack (illustrated)
  • A wave of vUE plug-in development, documentation, Github release, NPM package release
  • MMM, it smells good! Simplify ES functional programming core concepts
  • Vue Axios encapsulation and API interface management
  • Vue project issues and solutions that hit you hard