In this document, YARN is used as the package manager. The operation of NPM is similar.

Initialize the project

// Create an empty vue3-TS project,
yarn create vite my-vue-app --template vue-ts
// Install dependencies
cd my-vue-app && yarn
Git repository is not created by default
git init
Copy the code

The template does not use the esLint and Prettier configuration, so let’s install those dependencies in turn.

Integrated eslint

First we install ESLint

yarn add eslint  -D
Copy the code

Next initialize esLint:

npx eslint --init
Copy the code

Select these in turn:

At the last step, a prompt will pop up asking if you want to install the three dependencies immediately with NPM. Here, we select no and manually copy them out to install with YARN.

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

At this point, we have installed the dependencies and have a configured.eslintrc.json file:

{
    // Set our runtime environment to browser + ES2021 + Node, otherwise ESLint will report errors when encountering global objects such as Promises, Windows, etc
    "env": {
        "browser": true."es2021": true."node": true
    },
    // Inherit esLint's recommended rule set, vue's basic rule set, and typescript's rule set
    "extends": [
        "eslint:recommended"."plugin:vue/essential"."plugin:@typescript-eslint/recommended"].// Support the latest syntax for ts
    "parserOptions": {
        "ecmaVersion": 13."parser": "@typescript-eslint/parser"."sourceType": "module"
    },
    // Add vue and @typescript-esLint plugins to enhance ESLint capabilities
    "plugins": [
        "vue"."@typescript-eslint"]."rules": {}}Copy the code

We then add a lint command to the package.json file

{
    "scripts": {// lint files in the current project and enables automatic repair
        "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",}}Copy the code

Everything went well, however, when we ran the lint command, we found that the result was not what we wanted:

Parsing errors occur on the command line during the vue file. This is because, by default, ESLint does not parse vUE files, so we need an extra parser to parse vue files for us.

This step was configured for us by default when we inherited Plugin :vue/essential

But we extend “plugin:@typescript-eslint/recommended”, which in turn inherits from./node_modules/@typescript-eslint/eslint-plugin/dist/configs /base.js

Our extends order in the configuration file is:

{
    "extends": [
        "eslint:recommended"."plugin:vue/essential"."plugin:@typescript-eslint/recommended"],}Copy the code

So vue-eslint-parser is overridden by @typescript-esLint /parser. All we need to do is change the external parser to vUE -eslint-parser and add a parser:@typescript-eslint/parser attribute to parserOptions, which is already done in the configuration file.

{...// Add, parse vue file
    "parser":"vue-eslint-parser"."parserOptions": {
        "ecmaVersion": "latest"."parser": "@typescript-eslint/parser"."sourceType": "module"},... }Copy the code

The difference between the two parsers is that the outer parser parses vue files so that ESLint can parse the contents of the

If we continue to run YARN Run Lint, we will find another error:

Here are two questions,

  • <template>Nodes require one and only one root node
  • Can’t finddefinePropsThe definition of

/node_modules/eslint-plugin-vue./node_modules/eslint-plugin-vue Eslint-plugin-vue provides several default configuration sets.

A rule set without the prefix vue3- corresponds to a vue2 item, and a rule set starting with vue3- corresponds to a vue3 item. By default, we use vue/essential rule set. Since we are a vue3 project, we should use vue3 rule set. Vue3-recommended is used here

{
    "extends": [
        "eslint:recommended", -"plugin:vue/essential"The + +"plugin:vue/vue3-recommended"."plugin:@typescript-eslint/recommended"],}Copy the code

And then you run yarn Run Lint, and you still get an error.

Because defineProps is a global pre-compiled macro, ESLint doesn’t know where it is defined, so it needs to be marked in the global option, however when I read the eslint-plugin-vue file it is already preset.

We just need to turn on the environment variable in env:

{
    "env": {
        "browser": true."es2021": true."node": true.// Enable the setup syntax sugar environment
         ++ "vue/setup-compiler-macros":true}},Copy the code

And then we run YARN Run Lint,oh thank god, no error.

Add the VScode-esLint plugin

For now, we can use ESLint on the command line, but writing a single line of code to run a detection script is too cumbersome. Fortunately, we can use it with the VS code-esLint plugin.

Install the vscode-eslint plugin in vscode, it will lint our script as we write code, and we don’t need to run yarn run lint anymore. In the meantime, we can create a.vscode/settings.json file to enable automatic repair for this project

{
  "editor.codeActionsOnSave": {
    "source.fixAll": true}}Copy the code

This way, when you save by pressing CTRL + S, ESLint will intelligently fix some code errors for you.

Integrated prettier

Prettier is gentler than esLint. Prettier doesn’t give us many configuration options, so we just look for one on the Internet.

yarn add prettier -D
Copy the code

Then add a configuration file to the project root directory

// .prettierrc.js
module.exports = {
  printWidth: 80.// Single line length
  tabWidth: 2.// Indent length
  useTabs: false.// Use Spaces instead of TAB indentation
  semi: true.// Use a semicolon at the end of a sentence
  singleQuote: true.// Use single quotes
}
Copy the code

This is my configuration file, if you need more configuration methods, please refer to the official configuration documentation.

Then add a script to package.json

{
    "scripts": {"format": "prettier --write ./**/*.{vue,ts,tsx,js,jsx,css,less,scss,json,md}"}}Copy the code

When this command is run, all the files in our project are formatted once.

Generally speaking, we also need to integrate vscode-prettier for auto-save formatting, and add the following rule to our.vscode/settings.json after installing the plugin in the marketplace

{
   "editor.formatOnSave": true.// Enable auto save
   "editor.defaultFormatter": "esbenp.prettier-vscode".// The default formatting tool prettier is used
}
Copy the code

This way, when we write code in vscode, it will be automatically formatted.

Resolve the conflict between ESLint and Prettier

Ideally, when writing code at this point, ESLint and Prettier would work together to beautify our code and fix poor-quality code. However, the reality is not always perfect, and we will find that sometimes ESLint will give us an error, and when we modify it, the screen will blink for a while and then revert to the error state, and the autofix will fail.

That’s because SOME of the rules esLint uses to beautify code conflict with Prettier’s rules. Here’s my other blog, Resolving the Conflict between ESLint and Prettier. Use the rulesset provided by ESlint-config-Prettier to override conflicting esLint rules and use eslint-plugin-prettier to prettier code.

yarn add eslint-config-prettier eslint-plugin-prettier -D
Copy the code

Then add a configuration to the end of the extends in.eslintrc.json:

  "extends": [
    "eslint:recommended"."plugin:vue/vue3-recommended"."plugin:@typescript-eslint/recommended"."plugin:prettier/recommended" // Add, must be placed last].Copy the code

Then we reboot vscode and see that the conflict is gone and our autofix and autoformat work together.

Configure HusKY + Lint-staged

In theory, by the last step we were able to get our project into good development specification constraints. However, there are still areas for improvement:

  • If it’s in the middle of the projecteslint + prettierIf used with the original codeyarn run lint oryarn run formatThis is bound to lead to extensive changes and even conflict.
  • Not for somevscodeEditor, or not installedprettierandeslintAs far as users of plug-ins are concerned, they do not enjoy the assistance provided by plug-ins, and their code is most likely not conforming to the specification and should not be submitted to the code base.

Based on these concerns, the community has provided husKY + Lint-staged progressive approaches. Lint-staged is a lint-staged tool that only tests Git staging areas. Husky is a tool used to add Git hooks to our project. Git hooks are scripts triggered when performing Git operations, such as: The pre-commit hook is triggered when committing, and the commit-msg hook is triggered when entering the commit information. Using husky to install the pre-commit hook, we can run our script to check if the code to commit is normal at git commit time, so we can only check the files in the staging area.

First install dependencies

yarn add husky lint-staged -D
Copy the code

Add a preinstall script to package.json

{
    "script": {"prepare": "husky install"}}Copy the code

The prepare script will automatically run after yarn install, so husky will be automatically installed after your dependent partner has cloned your project. So we need to manually run yarn Run prepare and we’ll get a directory. Husky.

Next we add a pre-commit hook for our Git repository and run it

npx husky add .husky/pre-commit "npx --no-install lint-staged"
Copy the code

This time generate a pre-commit script in our.husky directory

#! /bin/sh 
. "$(dirname "$0")/_/husky.sh"

npx --no-install lint-staged
Copy the code

Next we configure Lint-staged, adding the following configuration information to package.json.

{
  "lint-staged": {
    "*.{js,vue,ts,jsx,tsx}": [
      "prettier --write"."eslint --fix"]."*.{html,css,less,scss,md}": [
      "prettier --write"]}}Copy the code

After that, the code we submit to the staging area is formatted and checked by ESLint + Prettier to make sure that the code is still standard.

Overview of configuration files

// package.json
{
  "name": "my-vue-app"."version": "0.0.0"."scripts": {
    "dev": "vite"."build": "vue-tsc --noEmit && vite build"."preview": "vite preview"."lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix"."format": "prettier --write ./**/*.{vue,ts,tsx,js,jsx,css,less,scss,json,md}"."prepare": "husky install"
  },
  "dependencies": {
    "vue": "^ 3.2.25"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^ 5.7.0"."@typescript-eslint/parser": "^ 5.7.0"."@vitejs/plugin-vue": "^ 2.0.0." "."eslint": "^ 8.4.1"."eslint-config-prettier": "^ 8.3.0"."eslint-plugin-prettier": "^ 4.0.0"."eslint-plugin-vue": "^ 8.2.0"."husky": "^ 7.0.4"."lint-staged": "^ 12.1.3." "."prettier": "^ 2.5.1." "."typescript": "^ 4.4.4." "."vite": "^ 2.7.2." "."vue-tsc": "^ 0.29.8"
  },
  "lint-staged": {
    "*.{js,vue,ts,jsx,tsx}": [
      "prettier --write"."eslint --fix"]."*.{html,css,less,scss,md}": [
      "prettier --write"]}}// .eslintrc.json
{
  "env": {
    "browser": true."es2021": true."node": true."vue/setup-compiler-macros": true
  },
  "extends": [
    "eslint:recommended"."plugin:vue/vue3-recommended"."plugin:@typescript-eslint/recommended"."plugin:prettier/recommended"]."parser": "vue-eslint-parser"."parserOptions": {
    "ecmaVersion": "latest"."parser": "@typescript-eslint/parser"."sourceType": "module"
  },
  "plugins": ["vue"."@typescript-eslint"]."rules": {}}// .prettierrc.js
module.exports = {
  printWidth: 80.// Single line length
  tabWidth: 2.// Indent length
  useTabs: false.// Use Spaces instead of TAB indentation
  semi: true.// Use a semicolon at the end of a sentence
  singleQuote: true.// Use single quotes
};

// .vscode/settings.json
{
  "editor.formatOnSave": true."editor.defaultFormatter": "esbenp.prettier-vscode"."editor.codeActionsOnSave": {
    "source.fixAll": true}}// .husky/pre-commit#! /bin/sh ."$(dirname "$0")/_/husky.sh"

npx --no-install lint-staged
Copy the code

conclusion

In this paper, esLint + Prettier + Husky + Lint-staged project specifications were added for a Viet-Vue3-TS project from actual combat, hoping that we could learn some knowledge from it. The code has been uploaded to Github and can be viewed here.

If you find this article helpful, please like 👍!