Introduction to the

Build the vuE3. X project engineering environment from scratch, integrate ESLint, Prettier, Stylelint, Husky, Lint-staged, etc

Warehouse address – Github, welcome to use and light up the little star.

Technology stack used

  • Build tool: Vite
  • Front-end framework: vue3.x
  • Programming language: TypeScript
  • Code specification:
    • ESLint
    • Prettier
    • Stylelint
  • Submission specification:
    • husky
    • lint-staged
  • CSS preprocessor: less
  • Routing tool: Vue Router 4
  • Status management: Vuex 4

viteInitialize the project

npm init vite@latest <project-name> vue-ts
Copy the code

aliasThe alias configuration

Modify thevite.config.js

// vite.config.js

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      NPM install @types/node --save-dev
      The '@': resolve(__dirname, 'src'),}}});Copy the code

Modify thetsconfig.json

"compilerOptions": {..."paths": {
      "@ / *": [ "./src/*"],}},Copy the code

configurationeslintprettier

Installation required dependencies

yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue prettier eslint-config-prettier eslint-plugin-prettier -D
Copy the code

add.eslintrc.jsAnd its configuration

module.exports = {
  parser: 'vue-eslint-parser'.extends: ['plugin:vue/recommended'.'plugin:prettier/recommended'].parserOptions: {
    parser: '@typescript-eslint/parser'.ecmaVersion: 2020.sourceType: 'module',},rules: {
    'generator-star-spacing': 'off'.'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'.semi: [2.'always'].'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false}].'no-undef': 'off'.'eol-last': [1.'always'].'no-mixed-spaces-and-tabs': 2.'prettier/prettier': [
      'error',
      { singleQuote: true.vueIndentScriptAndStyle: false.semi: true},].'vue/no-multiple-template-root': 0.// template checks the node only
    'vue/multi-word-component-names': 0,}};Copy the code

addprettier.config.jsAnd its configuration

module.exports = {
  printWidth: 100.tabWidth: 2.useTabs: false.semi: 'all'.// Open comma
  vueIndentScriptAndStyle: false.singleQuote: true./ / single quotation marks
  quoteProps: 'as-needed'.bracketSpacing: true.trailingComma: 'all'.// Final semicolon
  jsxBracketSameLine: false.jsxSingleQuote: false.arrowParens: 'always'.insertPragma: false.requirePragma: false.proseWrap: 'never'.htmlWhitespaceSensitivity: 'strict'.endOfLine: 'lf'};Copy the code

add.editorconfigAnd its configuration

EditorConfig helps maintain a consistent coding style for multiple developers working on the same project on different IDE editors

Root = true # Match all files [*] # Indent style, Indent_style = space # indent_size = 2 Optional "if", "or", "orif" end_of_line = lf # Set character set charset = UTF-8 # Remove before and after Spaces in a line TRIM_trailing_whitespace = true # Insert new line at end of file insert_final_newline = trueCopy the code

configurationstylelint

Stylelint is a CSS detector that lets developers write styles that follow consistent conventions, avoiding code clutter and unnecessary errors.

stylelint rules

Installation required dependencies

yarn add stylelint stylelint-config-recommended-vue stylelint-config-standard postcss-html postcss-less -D
Copy the code

add.stylelintrcAnd related dependencies

{
  "extends": ["stylelint-config-standard"."stylelint-config-recommended-vue"]."rules": {
    "no-empty-source": null."property-no-vendor-prefix": null."number-leading-zero": "always"."number-no-trailing-zeros": true."length-zero-no-unit": true."value-list-comma-space-after": "always"."declaration-colon-space-after": "always"."value-list-max-empty-lines": 0."shorthand-property-no-redundant-values": true."declaration-block-no-duplicate-properties": true."declaration-block-no-redundant-longhand-properties": true."declaration-block-semicolon-newline-after": "always"."block-closing-brace-newline-after": "always"."media-feature-colon-space-after": "always"."media-feature-range-operator-space-after": "always"."at-rule-name-space-after": "always"."indentation": 2."no-eol-whitespace": true."string-no-newline": null."string-quotes": "double"."at-rule-no-unknown": [ true, {
      "ignoreAtRules": [
        "/-/"]]}}}Copy the code

Configure the package.json script

{
    "scripts": {... ."lint:style": "stylelint \"src/**/*.(vue|less|css)\" --customSyntax postcss-less"}}Copy the code

Configure code inspection and submit specification hooks

Configuration husky

Husky official documentation

The installationhusky

yarn add husky --dev
Copy the code

To enable thegit hooks

yarn husky install
Copy the code

increasepre-commit

npx husky add .husky/pre-commit "npm run lint"
Copy the code

A pre-commit file is created in the.husky/ directory

configurationpackage.jsonThe script

{
    "scripts": {... ."lint": "eslint . --ext .js,.ts,.vue --ignore-path .gitignore"."prepare": "husky install"}}Copy the code

addcommitSubmission specificationgit hooks

npx husky add .husky/commit-msg 'yarn commitlint --edit "$1"'
Copy the code

The commit- MSG file is created in the.husky/ directory

addcommitlint.config.jsAnd related dependencies

Git Commit Proper posture: Commit Message writing Guide

yarn add @commitlint/cli @commitlint/config-conventional -D
Copy the code
module.exports = {
  extends: ['@commitlint/config-conventional'].rules: {
    'type-enum': [2.'always'['feat'.'fix'.'docs'.'style'.'refactor'.'test'.'chore']],
    'subject-full-stop': [0.'never'].'subject-case': [0.'never'],}};Copy the code

Configuration lint – staged

Lint-staged official documentation

Lint-staged submitted files will only be checked and repaired to ensure that the code complies with the project’s ESLint specifications.

The installation

yarn add lint-staged -D
Copy the code

add.lintstagedrcConfiguration files and dependencies

{
  "*.{js,ts,vue}": ["npm run lint"],
  "*.{vue,css,scss,sass,less}": ["npm run lint:style"]
}
Copy the code

Modify thepre-commitfile

#! /bin/sh . "$(dirname "$0")/_/husky.sh" - npm run lint + yarn lint-staged --allow-empty "$1"Copy the code

Validation code checks and submits the specification hook functionality

Code review

# to perform
git add .
git commit -m "test..."

# outputYarn Run v1.13.0 Warning package.json: No license field $/ VUe-base-project /node_modules/. Bin /lint-staged --allow-empty' '
✔ Preparing...
⚠ Running tasks...
  ❯ Running tasks for *.{js,ts,vue}
    ✖ npm run lint [FAILED]
  ❯ Running tasks for*. {HTML, vue, CSS, SCSS, sass, less} ✖ stylelint - fix (FAILED) left Skipped down because of the errors from the tasks. [Skipped] ✔ Reverting  to original state because of errors... ✔ Cleaning up... * Stylelint --fix: Error: No configuration Providedfor/vue-base-project/src/components/UserPane/UserInfo.vue at module.exports (/vue-base-project/node_modules/stylelint/lib/utils/configurationError.js:10:14) at getConfigForFile (/vue-base-project/node_modules/stylelint/lib/getConfigForFile.js:60:4) at async isPathIgnored (/vue-base-project/node_modules/stylelint/lib/isPathIgnored.js:25:17) at async lintSource (/vue-base-project/node_modules/stylelint/lib/lintSource.js:37:20) at async /vue-base-project/node_modules/stylelint/lib/standalone.js:218:27 at async Promise.all (index 0) at async standalone (/ vue - base - project/node_modules/stylelint/lib/standalone. Js: 257:22) ✖ NPM run lint: jsxBracketSameLine is deprecated. npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] lint: 'eslint. -- ext.js,.ts,.vue -- ignore-path.gitignore"/vue-base-project/commitlint.config.js" "/vue-base-project/src/components/UserPane/UserInfo.vue"` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] lint script.npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A completelog of this run can be found in:
npm ERR!     /.npm/_logs/2021-11-04T07_56_03_833Z-debug.log

> [email protected] lint /vue-base-project
> eslint . --ext .js,.ts,.vue --ignore-path .gitignore "/vue-base-project/commitlint.config.js" "/vue-base-project/src/components/UserPane/UserInfo.vue"


/vue-base-project/src/components/UserPane/UserInfo.vue
  9:51  error  Insert `;`         prettier/prettier
  9:51  error  Missing semicolon  semi

✖ 2 problems (2 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
husky - pre-commit hook exited with code 1 (error)
Copy the code

As can be seen from the error information, detect the submitted code, the SRC/components/UserPane/the UserInfo. Vue file existence is not in conformity with the eslint specification

Submit specifications

# to perform
git add .
git commit -m "test..."

# outputYarn Run v1.13.0 Warning package.json: No license field $/ VUe-base-project /node_modules/. Bin /lint-staged --allow-empty' '
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
✨  Done in2.50 S. YARN Run v1.13.0 Warning Package. json: No license field $/vue-base-project/node_modules/. Bin /commitlint -- edit. git/COMMIT_EDITMSG ⧗ input:test. * The subject may not be empty [subject-Empty] *typeMay not be empty [type-empty] * Found 2 problems, 0 warnings ⓘ Gethelp: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
husky - commit-msg hook exited with code 1 (error)
Copy the code

Git code submission: “test…” , does not meet the specification

configurationlessThe preprocessor

Installation required dependencies

yarn add less less-loader -D
Copy the code

lessThe global variable

addcustom.lessfile

@primary-color : #3e94e1;
Copy the code

Modify thevite.config.tsconfiguration

export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        additionalData: `@import "${resolve(__dirname, 'src/assets/css/custom.less')}"; `,},},},});Copy the code

To introduce the normalize. CSS

normalize.css

configurationvue-router

The installation

yarn add vue-router@4
Copy the code

addrouterDirectory and Configuration

createrouter/index.tsfile

// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  {
    path: '/'.name: 'home'.component: () = > import('@/views/Home/index.vue'),}, {path: '/user'.name: 'user'.component: () = > import('@/views/User/index.vue'),},];const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;
Copy the code

registeredrouterThe instance

import { createApp } from 'vue';
import App from './App.vue';
import router from '@/router/index';

const app = createApp(App);
app.use(router);
app.mount('#app');
Copy the code

Use the sample

<template>
  <button @click="toPage('home')">to home page</button>

  <button @click="toPage('user')">to user page</button>
  <br />
  <br />
  <br />
  <router-view></router-view>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { useRouter } from 'vue-router';

export default defineComponent({
  setup() {
    const router = useRouter();
    const toPage = (name: string) = > {
      router.push({
        name,
      });
    };
    return{ toPage, }; }});</script>

<style></style>
Copy the code

configurationvuex

The installation

yarn add vuex@next --save
Copy the code

addstoreDirectory and Configuration

The directory structure

├ ─ ─ store │ ├ ─ ─ getters. Ts │ ├ ─ ─ but ts │ └ ─ ─ modules │ └ ─ ─ the user. The tsCopy the code

createuserStore ModuleThe instance

import { UserInfoType } from '@/types/user';

import { fetchUsetInfo } from '@/api/user';

const userStore = {
  namespaced: true.state() {
    return {
      info: {
        name: ' '.desc: ' ',}}; },mutations: {
    SET_USER_INFO(state: any, info: UserInfoType){ state.info = info; }},actions: {
    getUserInfo({ commit }: any, name: string) {
      return new Promise((resolve, reject) = > {
        fetchUsetInfo(name)
          .then((response) = > {
            commit('SET_USER_INFO', response);
            resolve(response);
          })
          .catch((error) = >{ reject(error); }); }); ,}}};export default userStore;
Copy the code

createstore

import { createStore } from 'vuex';
import user from './modules/user';
import getters from './getters';

const store = createStore({
  modules: {
    user,
  },
  getters,
});

export default store;
Copy the code

registeredstoreThe instance

import { createApp } from 'vue';
import App from './App.vue';
import store from '@/store/index';

const app = createApp(App);
app.use(store);
app.mount('#app');
Copy the code

Use the sample

<template>
  <div class="user-info">
    <div>name: {{ userInfo.name }}</div>
    <div>desc: {{ userInfo.desc }}</div>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, computed } from 'vue';
import { useStore } from 'vuex';

export default defineComponent({
  props: {
    count: {
      type: String.default: null,}},setup(props) {
    const store = useStore();

    const getUserInfo = async (name: string) => {
      store.dispatch('user/getUserInfo', name);
    };

    onMounted(() = > {
      getUserInfo('yoo');
    });

    return {
      userInfo: computed(() = >store.getters.userInfo), }; }});</script>
Copy the code

FAQ

The template root requires exactly one element

The reason:

Vue3 supports multiple nodes under template, which is not allowed in VUE2

Solutions:

  1. The Vetur plugin modifs the configuration, set => preferences => search for “esLint” => uncheck under VeturVetur template validation
  2. Eslint rules to increase
rules: {
    ...
    'vue/no-multiple-template-root': 0.// template checks the node only
},
Copy the code

ESLint, Prettier configuration conflicts in VSCode

To modify the default prettier configuration, override the setting of the prettier plug-in in.eslintrc.js. Rules need to be configured.

rules: {
    ...
    'prettier/prettier': ['error', { singleQuote: true.parser: 'flow'.semi: true}],},Copy the code

The cause and solution of configuration conflict between ESLint and Prettier in VSCode

Description The Vite alias failed to import ts files

Add configuration to tsconfig.json:

"compilerOptions": {..."paths": {
      "@ / *": [ "./src/*"],}},Copy the code

stylelintdetection.vueFile promptUnknown word CssSyntaxError

The reason:

Styleliint does not parse Stylus directly in vue files; additional plug-in support is required

postcss-html#linting-with-stylelint

Solutions:

Install plug-in:

yarn add stylelint-config-recommended-vue postcss-html postcss-less -D
Copy the code

Modify.stylelintrc configuration:

{-"extends": ["stylelint-config-standard"],

    + "extends": ["stylelint-config-standard"."stylelint-config-recommended-vue"],}Copy the code

Modify package.json lint:style script:

"scripts": {
    "lint:style": "stylelint \"src/**/*.(vue|less|css)\" --customSyntax postcss-less"
}
Copy the code

conclusion

This paper mainly explains how to set up the vuE3. X project engineering environment step by step, and how to restrict the code specification and submission, basically covering the whole process of the early stage of a project.

The length is a little long, welcome to correct any mistakes, thank you for your support!

❤️ ❤️ ❤️ ❤ ❤️