Error[8]: Undefined offset: 851, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

初始化项目
// 创建一个空的 vue3-ts 项目,
yarn create vite my-vue-app --template vue-ts
// 安装依赖
cd my-vue-app && yarn
// 默认是没有创建git仓库的,这里我们初始化一下
git init

这个模板是没有使用配置eslintprettier的,接下来我们依次安装这些依赖。

集成eslint

首先我们安装eslint

yarn add eslint  -D

接下来初始化eslint:

npx eslint --init

依次选择这些选项:

询问:How would you like to use ESLint? ...
选择:To check syntax and find problems

询问:What type of modules does your project use? ...
选择:JavaScript modules (import/export)

询问:Which framework does your project use? ...
选择:Vue.js

询问:Does your project use TypeScript?
选择:yes

询问:Where does your code run? ...
选择:Browser  (node服务端选择node项)

询问:What format do you want your config file to be in? ...
选择:JavaScript

询问:Would you like to install them now with npm?
选择:yes
...

到这一步,我们就已经安装了相关的依赖了,并且得到一个已配置好的.eslintrc.json文件:

{
    // 设置我们的运行环境为浏览器 + es2021 + node ,否则eslint在遇到 Promise,window等全局对象时会报错
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    // 继承eslint推荐的规则集,vue基本的规则集,typescript的规则集
    "extends": [
        "eslint:recommended",
        "plugin:vue/essential",
        "plugin:@typescript-eslint/recommended"
    ],
    // 支持ts的最新语法
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    // 添加vue和@typescript-eslint插件,增强eslint的能力
    "plugins": [
        "vue",
        "@typescript-eslint"
    ],
    "rules": {
    }
}

然后我们为package.json文件增加一个lint命令

{
    "scripts":{
        // lint当前项目中的文件并且开启自动修复
        "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
    }
}

一切进行得非常顺利,然而当我们运行lint命令时,会发现不是我们想要的结果:

命令行在解析vue文件会报parsing error。这是因为,默认eslint不会解析vue文件,所以我们需要一个额外的解析器来帮我们解析vue文件。

这一步本来是在我们继承plugin:vue/essential的时候,默认为我们配置了的

但是我们后续又extend"plugin:@typescript-eslint/recommended",它又继承来自./node_modules/@typescript-eslint/eslint-plugin/dist/configs/base.js

而我们在配置文件中的extends顺序是:

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

所以vue-eslint-parser@typescript-eslint/parser覆盖了。这里我们只需要将外部的parser改为vue-eslint-parser,并且在parserOptions中添加一个parser:@typescript-eslint/parser属性即可,而这一步我们之前的配置文件里面已经有做了。这里可以查看官方说明eslint-plugin-vue

{
    ...
    // 新增,解析vue文件
    "parser":"vue-eslint-parser",
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    ...
}

两个parser的区别在于,外面的parser用来解析vue文件,使得eslint能解析标签中的内容,而parserOptions中的parser,即@typescript-eslint/parser`用来解析vue文件中``标签中的代码。

接下来我们继续运行 yarn run lint,会发现又报错了:

`节点要求有且只有一个根节点找不到defineProps的定义

我们知道,这两个特性都是vue3引入的,问题可能出在我们的配置不支持vue3项目,翻阅./node_modules/eslint-plugin-vue目录的相关配置,便可发现问题所在,eslint-plugin-vue提供了几个预设的配置集。

没有vue3-前缀的规则集对应vue2项目,vue3-开头的对应vue3项目。而我们默认使用的是 vue/essential这个规则集,由于我们是vue3项目,所以应该使用vue3的规则集,这里使用vue3-recommended

{
    "extends": [
        "eslint:recommended",
        -- "plugin:vue/essential",
        ++ "plugin:vue/vue3-recommended",
        "plugin:@typescript-eslint/recommended"
    ],
}

然后再运行,yarn run lint,发现还是会报错。

因为defineProps是一个全局的预编译宏,eslint不知其定义在哪里,所以需要在global选项中将其标注出来,然而我阅读了eslint-plugin-vue这个文件后,发现它已经预设了。

我们只需要在env中开启这个环境变量即可:

{
    "env": {
        "browser": true,
        "es2021": true,
        "node": true,
        // 开启setup语法糖环境
         ++ "vue/setup-compiler-macros":true
    },
}

然后我们再运行yarn run lint,oh 谢天谢地,终于不报错了。

添加vscode-eslint 插件

就目前而言,我们能在命令行中使用eslint了,然而写一行代码就去运行下检测脚本实在太麻烦,好在我们可以结合vscode-eslint插件使用。

vscode中安装好vscode-eslint插件,它便会在我们写代码的时候对我们的脚本进行lint,我们就没必要再运行yarn run lint 了。同时,我们可以新建一个.vscode/settings.json文件,为这个本项目开启自动修复

{
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

这样一来,当你按下ctrl + s保存的时候,eslint便会智能地为你修复一些代码错误了。

安装依赖说明 eslint: JavaScript 和 JSX 检查工具eslint-config-standard: 目前比较流行的 JavaScript 代码规范eslint-plugin-vue: 使用 ESLint 检查 .vue文件 的 ` 和 ``eslint-plugin-prettier: 基于 prettier 代码风格的 eslint 规则eslint-config-prettier: 禁用所有与格式相关的 eslint 规则,解决 prettier 与 eslint 规则冲突,确保将其放在 extends 队列最后,这样它将覆盖其他配置 集成 prettier

相比 eslint 而言 prettier 就会要温和一些了。 prettier 并没有提供太多的配置选项给我们选择,所以我们在网上随便找一份配置就行。

yarn add prettier -D

然后再项目根目录添加一份配置文件

// .prettierrc.js
module.exports = {
  printWidth: 80, //单行长度
  tabWidth: 2, //缩进长度
  useTabs: false, //使用空格代替tab缩进
  semi: true, //句末使用分号
  singleQuote: true, //使用单引号
}

这是我的配置文件,如果需要更多的配置方法,可以参考官方的配置文档。

然后再package.json中添加一个脚本

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

当运行这个命令时,就会将我们项目中的文件都格式化一次。

一般而言,我们还需要集成 vscode-prettier这个插件来完成自动保存格式化,在插件市场安装好了以后,在我们的.vscode/settings.json中添加如下规则

{
   "editor.formatOnSave": true, // 开启自动保存
   "editor.defaultFormatter": "esbenp.prettier-vscode", // 默认格式化工具选择prettier
}

这样一来,当我们在vscode写代码的时候,便会自动格式化了。

解决 eslint 和 prettier 的冲突

理想状态下,到这一步我们写代码的时候,eslintprettier会相互协作,既美化我们的代码,也修复我们质量不过关的代码。然而现实总是不那么完美,我们会发现某些时候,eslint提示错误,我们修改了以后,屏幕会闪一下然后又恢复到报错状态,自动修复失效了。

这是因为eslint 有一部分负责美化代码的规则和 prettier的规则冲突了,这里可以参考我的另外一篇博客《解决Eslint 和 Prettier 之间的冲突》,这里我们只给出方案。 用 eslint-config-prettier 提供的规则集来覆盖掉eslint冲突的规则,并用eslint-plugin-prettier来使eslint使用prettier的规则来美化代码。

yarn add eslint-config-prettier eslint-plugin-prettier -D

然后在 .eslintrc.jsonextends的最后添加一个配置:

  "extends": [
    "eslint:recommended",
    "plugin:vue/vue3-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended" // 新增,必须放在最后面
  ],

然后我们重启一下vscode,就会发现冲突消失了,我们的自动修复和自动格式化也能相互协作了。

配置 husky + lint-staged

理论上,到上一步我们已经能使得我们的项目获得不错的开发规范约束了。然而仍然有可以改进的地方:

如果是在项目中途才接入eslint + prettier,如果对原来的代码使用yarn run lint 或者 yarn run format势必会带来大范围地改动,甚至会造成冲突。对于一些不使用vscode编辑器,或者没有安装prettiereslint插件的用户而言,他们不能享受到插件带来的协助,而他们的代码自然大概率是不符合规范的,不该被提交到代码库。

基于上述的顾虑,社区提供了 husky + lint-staged的渐进式方案。 lint-staged 是一个只检测git暂存区的lint工具,husky是一个用来给我们的项目添加git hook的工具,git hook是进行git *** 作会触发的脚本,例如:提交的时候会触发pre-commit钩子,输入提交信息会触发commit-msg钩子。 我们用husky安装pre-commit钩子,我们就可以在进行git commit *** 作的时候,运行我们的脚本来检测待提交的代码是否规范,便可以只对暂存区的文件进行检查。

首先安装依赖

yarn add husky lint-staged -D

添加一个在package.json中添加一条preinstall脚本

{
    "script":{
        "prepare": "husky install"
    }
}

prepare脚本会在 yarn install 之后自动运行,这样依赖你的小伙伴clone了你的项目之后会自动安装husky,这里由于我们已经运行过 yarn install 了,所以我们需要手动运行一次yarn run prepare,然后我们就会得到一个目录.husky

接下来我们为我们git仓库添加一个pre-commit钩子,运行

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

这回在我们的.husky目录下生成一个pre-commit的脚本

#!/bin/sh 
. "$(dirname ")"lint-staged/_/husky.sh"

npx --no-install lint-staged

接下来我们配置package.json,在"lint-staged"中添加下面的配置信息。

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

这样之后,我们后续提交到暂存区的代码也就会被eslint+prettier格式化和检查,进一步保证我们的代码规范。

配置 husky + lint-staged 后带来了新的Windows冲突问题 问题背景

pre-commit笔记本上新拉完代码,在执行Delete `␍`eslint(prettier/prettier) 复制代码 时,出现如下错误:

Crtl+S

下面是几种个人尝试过的解决方案:

解决方案 一、Crtl+S保存文件

eslint保存当前报错文件,eslint错误消失,这里我尝试网上提供的这个解决方案没有用,反而是我重启一下vscode编辑器报错没有了,不过总之这个方案是不行的

二、yarn run lint --fix

比上面省事,Working tree错误消失,但暂存区多了n个文件改动记录,对比commit也没发现任何不同。

缺点:需要.prettierrc所有文件,多余。

参考资料:“error Delete ⏎ prettier/prettier” in .vue files``

三、配置.prettierrc文件

在项目根目录下的prettier文件中写入即可。其实就是不让"endOfLine": "auto" 检测文件每行结束的格式.

git

缺点:不能兼容跨平台开发,从前端工程化上讲没有做到尽善尽美。

[参考资料:Why do I keep getting Delete ‘cr’ prettier/prettier]?

四、通过IDE一键切换

这是评论区掘金同道提供的方法,一般IDE下方状态栏会提供“切换行尾序列”的工具,如上图,一键切换到正确的行尾序列即可。

缺点:只能修复当前文件,不能解决整个项目报错的问题。

五、最佳方案

问题根源:

罪魁祸首是core.autocrlf 的一个配置属性:windows

由于历史原因,linux下和* Windows在换行的时候,同时使用了回车符CR(carriage-return character)和换行符LF(linefeed character) * 而Mac和Linux系统,仅仅使用了换行符LF * 老版本的Mac系统使用的是回车符CR 下的文本文件的换行符不一致。

Windows
Linux
Linux/MacOld Mac(pre-OSXCRLF
LFCR‘\n\r’
‘\n’‘\r’

因此,文本文件在不同系统下创建和使用时就会出现不兼容的问题。

我的项目仓库中默认是LF环境下提交的代码,文件默认是以windows结尾的(工程化需要,统一标准)。

当我用git clone电脑autocrlf代码的时候,若我的windows(在git下安装true,该选项默认为true)为CRLF,那么文件每行会被自动转成以pre-commit结尾,若对文件不做任何修改,eslint执行CR的时候就会提示你删除ctrl+s

现在可以理解yarn run lint --fixeslint方案为何可以修复Git错误了吧,因为CRLF自动将LF转换成了VScode

最佳实践:

现在Notepad++LF编辑器都能够自动识别文件的换行符是CRLF还是windows。 如果你用的是UTF-8,文件编码是autocrlf且包含中文,最好全局将false设置为git config --global core.autocrlf false

git

注意:'crlf'全局配置之后,你需要重新拉取代码。

由于我们组内全部使用的windows,所有直接配置.prettierrc

endOfLine: // package.json, // Windows
配置文件总览
"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"
   :"@types/node" {
    :"^16.3.1" ,"@typescript-eslint/eslint-plugin"
    :"^5.22.0" ,"@typescript-eslint/parser"
    :"^5.22.0" ,"@vitejs/plugin-vue"
    :"^1.2.4" ,"@vitejs/plugin-vue-jsx"
    :"^1.1.6" ,"@vue/compiler-sfc"
    :"^3.0.5" ,"eslint"
    :"^8.15.0" ,"eslint-config-prettier"
    :"^8.5.0" ,"eslint-config-standard"
    :"^17.0.0" ,"eslint-plugin-prettier"
    :"^4.0.0" ,"eslint-plugin-vue"
    :"^8.7.1" ,"husky"
    :"^8.0.1" ,"lint-staged"
    :"^12.4.1" ,"prettier"
    :"^2.6.2" ,"typescript"
    :"^4.3.2" ,"vite"
    :"^2.8.6" ,"vue-tsc"
    :"^0.33.9" }
  "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.js

.
module=exports // 设置我们的运行环境为浏览器 + es2021 + node ,否则eslint在遇到 Promise,window等全局对象时会报错 {
  env
  :browser {
    :true ,es2021
    :true ,node
    :true ,// 开启setup语法糖环境
    'vue/setup-compiler-macros'
    :true ,}
  ,// 继承eslint推荐的规则集,vue基本的规则集,typescript的规则集

  extends
  :[ 'plugin:vue/vue3-recommended'
    ,'plugin:@typescript-eslint/recommended'
    ,'standard'
    ,// 格式化规范 'plugin:prettier/recommended'
    ,// 新增,必须放在最后面,prettier规则覆盖与eslint冲突的规则 'prettier'
    ,// 避免vue 与 prettier冲突 'eslint:recommended'
    ,]
  ,// 定义ESLint的解析器

  parser
  :'vue-eslint-parser' ,// 支持ts的最新语法

  parserOptions
  :ecmaVersion {
    :'latest' ,parser
    :'@typescript-eslint/parser' ,sourceType
    :'module' ,}
  ,// 添加vue和@typescript-eslint插件,增强eslint的能力

  plugins
  :[ 'vue','@typescript-eslint' ,'prettier' ],rules

  :// "off"或者0    //关闭规则关闭 {
    // "warn"或者1    //在打开的规则作为警告(不影响退出代码)
    // "error"或者2    //把规则作为一个错误(退出代码触发时为1)
    'no-console'

    :. process.envNODE_ENV=== 'production' ? 'error' : 'off' ,'no-debugger'
    :. process.envNODE_ENV=== 'production' ? 'error' : 'off' ,// 解析vue模板错误规则
    'vue/no-parsing-error'
    :[ 2
      ,'x-invalid-end-tag'
      {
        :false ,'missing-semicolon-after-character-reference'
        :false ,}
      ,]
    ,'no-unused-expressions'
    :[ 'error',allowShortCircuit { :true ,allowTernary :true } ],// 允许使用短路、三目 'no-param-reassign'
    :[ 'error',props { :false } ],// 函数形参可修改 'vue/multi-word-component-names'
    :'off' ,// eslint-plugin-vue @8版本中新增了不少的规则,第一条就是 **‘vue/multi-word-component-names’: ‘error’,**所有index.vue 会报错,解决方法: 'no-new-object'
    :'off' ,// 关闭不可以new对象的规则 'no-explicit-any'
    :'off' ,// 可以使用any,但请尽量不使用any '@typescript-eslint/no-explicit-any'
    :'off' ,// ts可以使用any 'vue/v-on-event-hyphenation'
    :'off' ,// 关闭事件命名样式需要用连字符 }
  ,}
;// .prettierrc.js

/** 
  tips:
    endOfLine: 'crlf' 因为eslint和prettier就这个问题上不一致互相冲突,我们这里统一使用Windows系统的.
    如果是有mac使用需求的请使用git config --global core.autocrlf false解决
 */

.
module=exports printWidth {
  :100 ,//单行长度 tabWidth
  :2 ,//缩进长度 useTabs
  :false ,//使用空格代替tab缩进 semi
  :true ,//句末使用分号 singleQuote
  :true ,//使用单引号 endOfLine
  :'crlf' ,// Windows }
;// .vscode/settings.json



"editor.formatOnSave"
{
  :true ,"editor.defaultFormatter"
  :"esbenp.prettier-vscode" ,"editor.codeActionsOnSave"
  :"source.fixAll" {
    :true }
  }
// .husky/pre-commit

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

npx -no-install lintstaged
鸣谢

参考:

幕小白 项目中 Prettier + Stylelint + ESlint 配置
eslint-plugin-vue
羽徵 — Delete [+++]eslint(prettier/prettier) 错误的解决方案
羽墨 项目中 Prettier + Stylelint + ESlint 配置
Eslint与Prettier冲突解决,及eslint 问题记录

感谢各位开源作者

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
vue3 +vite+ts实战项目添加 eslint + prettier + lint-staged 踩坑指南_html-js-css_内存溢出

vue3 +vite+ts实战项目添加 eslint + prettier + lint-staged 踩坑指南

vue3 +vite+ts实战项目添加 eslint + prettier + lint-staged 踩坑指南,第1张

初始化项目
// 创建一个空的 vue3-ts 项目,
yarn create vite my-vue-app --template vue-ts
// 安装依赖
cd my-vue-app && yarn
// 默认是没有创建git仓库的,这里我们初始化一下
git init

这个模板是没有使用配置eslintprettier的,接下来我们依次安装这些依赖。

集成eslint

首先我们安装eslint

yarn add eslint  -D

接下来初始化eslint:

npx eslint --init

依次选择这些选项:

询问:How would you like to use ESLint? ...
选择:To check syntax and find problems

询问:What type of modules does your project use? ...
选择:JavaScript modules (import/export)

询问:Which framework does your project use? ...
选择:Vue.js

询问:Does your project use TypeScript?
选择:yes

询问:Where does your code run? ...
选择:Browser  (node服务端选择node项)

询问:What format do you want your config file to be in? ...
选择:JavaScript

询问:Would you like to install them now with npm?
选择:yes
...

到这一步,我们就已经安装了相关的依赖了,并且得到一个已配置好的.eslintrc.json文件:

{
    // 设置我们的运行环境为浏览器 + es2021 + node ,否则eslint在遇到 Promise,window等全局对象时会报错
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    // 继承eslint推荐的规则集,vue基本的规则集,typescript的规则集
    "extends": [
        "eslint:recommended",
        "plugin:vue/essential",
        "plugin:@typescript-eslint/recommended"
    ],
    // 支持ts的最新语法
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    // 添加vue和@typescript-eslint插件,增强eslint的能力
    "plugins": [
        "vue",
        "@typescript-eslint"
    ],
    "rules": {
    }
}

然后我们为package.json文件增加一个lint命令

{
    "scripts":{
        // lint当前项目中的文件并且开启自动修复
        "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
    }
}

一切进行得非常顺利,然而当我们运行lint命令时,会发现不是我们想要的结果:

命令行在解析vue文件会报parsing error。这是因为,默认eslint不会解析vue文件,所以我们需要一个额外的解析器来帮我们解析vue文件。

这一步本来是在我们继承plugin:vue/essential的时候,默认为我们配置了的

但是我们后续又extend"plugin:@typescript-eslint/recommended",它又继承来自./node_modules/@typescript-eslint/eslint-plugin/dist/configs/base.js

而我们在配置文件中的extends顺序是:

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

所以vue-eslint-parser@typescript-eslint/parser覆盖了。这里我们只需要将外部的parser改为vue-eslint-parser,并且在parserOptions中添加一个parser:@typescript-eslint/parser属性即可,而这一步我们之前的配置文件里面已经有做了。这里可以查看官方说明eslint-plugin-vue

{
    ...
    // 新增,解析vue文件
    "parser":"vue-eslint-parser",
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": "@typescript-eslint/parser",
        "sourceType": "module"
    },
    ...
}

两个parser的区别在于,外面的parser用来解析vue文件,使得eslint能解析标签中的内容,而parserOptions中的parser,即@typescript-eslint/parser`用来解析vue文件中``标签中的代码。

接下来我们继续运行 yarn run lint,会发现又报错了:

`节点要求有且只有一个根节点找不到defineProps的定义

我们知道,这两个特性都是vue3引入的,问题可能出在我们的配置不支持vue3项目,翻阅./node_modules/eslint-plugin-vue目录的相关配置,便可发现问题所在,eslint-plugin-vue提供了几个预设的配置集。

没有vue3-前缀的规则集对应vue2项目,vue3-开头的对应vue3项目。而我们默认使用的是 vue/essential这个规则集,由于我们是vue3项目,所以应该使用vue3的规则集,这里使用vue3-recommended

{
    "extends": [
        "eslint:recommended",
        -- "plugin:vue/essential",
        ++ "plugin:vue/vue3-recommended",
        "plugin:@typescript-eslint/recommended"
    ],
}

然后再运行,yarn run lint,发现还是会报错。

因为defineProps是一个全局的预编译宏,eslint不知其定义在哪里,所以需要在global选项中将其标注出来,然而我阅读了eslint-plugin-vue这个文件后,发现它已经预设了。

我们只需要在env中开启这个环境变量即可:

{
    "env": {
        "browser": true,
        "es2021": true,
        "node": true,
        // 开启setup语法糖环境
         ++ "vue/setup-compiler-macros":true
    },
}

然后我们再运行yarn run lint,oh 谢天谢地,终于不报错了。

添加vscode-eslint 插件

就目前而言,我们能在命令行中使用eslint了,然而写一行代码就去运行下检测脚本实在太麻烦,好在我们可以结合vscode-eslint插件使用。

vscode中安装好vscode-eslint插件,它便会在我们写代码的时候对我们的脚本进行lint,我们就没必要再运行yarn run lint 了。同时,我们可以新建一个.vscode/settings.json文件,为这个本项目开启自动修复

{
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

这样一来,当你按下ctrl + s保存的时候,eslint便会智能地为你修复一些代码错误了。

安装依赖说明 eslint: JavaScript 和 JSX 检查工具eslint-config-standard: 目前比较流行的 JavaScript 代码规范eslint-plugin-vue: 使用 ESLint 检查 .vue文件 的 ` 和 ``eslint-plugin-prettier: 基于 prettier 代码风格的 eslint 规则eslint-config-prettier: 禁用所有与格式相关的 eslint 规则,解决 prettier 与 eslint 规则冲突,确保将其放在 extends 队列最后,这样它将覆盖其他配置 集成 prettier

相比 eslint 而言 prettier 就会要温和一些了。 prettier 并没有提供太多的配置选项给我们选择,所以我们在网上随便找一份配置就行。

yarn add prettier -D

然后再项目根目录添加一份配置文件

// .prettierrc.js
module.exports = {
  printWidth: 80, //单行长度
  tabWidth: 2, //缩进长度
  useTabs: false, //使用空格代替tab缩进
  semi: true, //句末使用分号
  singleQuote: true, //使用单引号
}

这是我的配置文件,如果需要更多的配置方法,可以参考官方的配置文档。

然后再package.json中添加一个脚本

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

当运行这个命令时,就会将我们项目中的文件都格式化一次。

一般而言,我们还需要集成 vscode-prettier这个插件来完成自动保存格式化,在插件市场安装好了以后,在我们的.vscode/settings.json中添加如下规则

{
   "editor.formatOnSave": true, // 开启自动保存
   "editor.defaultFormatter": "esbenp.prettier-vscode", // 默认格式化工具选择prettier
}

这样一来,当我们在vscode写代码的时候,便会自动格式化了。

解决 eslint 和 prettier 的冲突

理想状态下,到这一步我们写代码的时候,eslintprettier会相互协作,既美化我们的代码,也修复我们质量不过关的代码。然而现实总是不那么完美,我们会发现某些时候,eslint提示错误,我们修改了以后,屏幕会闪一下然后又恢复到报错状态,自动修复失效了。

这是因为eslint 有一部分负责美化代码的规则和 prettier的规则冲突了,这里可以参考我的另外一篇博客《解决Eslint 和 Prettier 之间的冲突》,这里我们只给出方案。 用 eslint-config-prettier 提供的规则集来覆盖掉eslint冲突的规则,并用eslint-plugin-prettier来使eslint使用prettier的规则来美化代码。

yarn add eslint-config-prettier eslint-plugin-prettier -D

然后在 .eslintrc.jsonextends的最后添加一个配置:

  "extends": [
    "eslint:recommended",
    "plugin:vue/vue3-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended" // 新增,必须放在最后面
  ],

然后我们重启一下vscode,就会发现冲突消失了,我们的自动修复和自动格式化也能相互协作了。

配置 husky + lint-staged

理论上,到上一步我们已经能使得我们的项目获得不错的开发规范约束了。然而仍然有可以改进的地方:

如果是在项目中途才接入eslint + prettier,如果对原来的代码使用yarn run lint 或者 yarn run format势必会带来大范围地改动,甚至会造成冲突。对于一些不使用vscode编辑器,或者没有安装prettiereslint插件的用户而言,他们不能享受到插件带来的协助,而他们的代码自然大概率是不符合规范的,不该被提交到代码库。

基于上述的顾虑,社区提供了 husky + lint-staged的渐进式方案。 lint-staged 是一个只检测git暂存区的lint工具,husky是一个用来给我们的项目添加git hook的工具,git hook是进行git *** 作会触发的脚本,例如:提交的时候会触发pre-commit钩子,输入提交信息会触发commit-msg钩子。 我们用husky安装pre-commit钩子,我们就可以在进行git commit *** 作的时候,运行我们的脚本来检测待提交的代码是否规范,便可以只对暂存区的文件进行检查。

首先安装依赖

yarn add husky lint-staged -D

添加一个在package.json中添加一条preinstall脚本

{
    "script":{
        "prepare": "husky install"
    }
}

prepare脚本会在 yarn install 之后自动运行,这样依赖你的小伙伴clone了你的项目之后会自动安装husky,这里由于我们已经运行过 yarn install 了,所以我们需要手动运行一次yarn run prepare,然后我们就会得到一个目录.husky

接下来我们为我们git仓库添加一个pre-commit钩子,运行

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

这回在我们的.husky目录下生成一个pre-commit的脚本

#!/bin/sh 
. "$(dirname ")"lint-staged/_/husky.sh"

npx --no-install lint-staged

接下来我们配置package.json,在"lint-staged"中添加下面的配置信息。

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

这样之后,我们后续提交到暂存区的代码也就会被eslint+prettier格式化和检查,进一步保证我们的代码规范。

配置 husky + lint-staged 后带来了新的Windows冲突问题 问题背景

pre-commit笔记本上新拉完代码,在执行Delete `␍`eslint(prettier/prettier) 复制代码 时,出现如下错误:

Crtl+S

下面是几种个人尝试过的解决方案:

解决方案 一、Crtl+S保存文件

eslint保存当前报错文件,eslint错误消失,这里我尝试网上提供的这个解决方案没有用,反而是我重启一下vscode编辑器报错没有了,不过总之这个方案是不行的

二、yarn run lint --fix

比上面省事,Working tree错误消失,但暂存区多了n个文件改动记录,对比commit也没发现任何不同。

缺点:需要.prettierrc所有文件,多余。

参考资料:“error Delete ⏎ prettier/prettier” in .vue files``

三、配置.prettierrc文件

在项目根目录下的prettier文件中写入即可。其实就是不让"endOfLine": "auto" 检测文件每行结束的格式.

git

缺点:不能兼容跨平台开发,从前端工程化上讲没有做到尽善尽美。

[参考资料:Why do I keep getting Delete ‘cr’ prettier/prettier]?

四、通过IDE一键切换

这是评论区掘金同道提供的方法,一般IDE下方状态栏会提供“切换行尾序列”的工具,如上图,一键切换到正确的行尾序列即可。

缺点:只能修复当前文件,不能解决整个项目报错的问题。

五、最佳方案

问题根源:

罪魁祸首是core.autocrlf 的一个配置属性:windows

由于历史原因,linux下和* Windows在换行的时候,同时使用了回车符CR(carriage-return character)和换行符LF(linefeed character) * 而Mac和Linux系统,仅仅使用了换行符LF * 老版本的Mac系统使用的是回车符CR 下的文本文件的换行符不一致。

Windows
Linux
Linux/MacOld Mac(pre-OSXCRLF
LFCR‘\n\r’
‘\n’‘\r’

因此,文本文件在不同系统下创建和使用时就会出现不兼容的问题。

我的项目仓库中默认是LF环境下提交的代码,文件默认是以windows结尾的(工程化需要,统一标准)。

当我用git clone电脑autocrlf代码的时候,若我的windows(在git下安装true,该选项默认为true)为CRLF,那么文件每行会被自动转成以pre-commit结尾,若对文件不做任何修改,eslint执行CR的时候就会提示你删除ctrl+s

现在可以理解yarn run lint --fixeslint方案为何可以修复Git错误了吧,因为CRLF自动将LF转换成了VScode

最佳实践:

现在Notepad++LF编辑器都能够自动识别文件的换行符是CRLF还是windows。 如果你用的是UTF-8,文件编码是autocrlf且包含中文,最好全局将false设置为git config --global core.autocrlf false

git

注意:'crlf'全局配置之后,你需要重新拉取代码。

由于我们组内全部使用的windows,所有直接配置.prettierrc

endOfLine: // package.json, // Windows
配置文件总览
"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"
   :"@types/node" {
    :"^16.3.1" ,"@typescript-eslint/eslint-plugin"
    :"^5.22.0" ,"@typescript-eslint/parser"
    :"^5.22.0" ,"@vitejs/plugin-vue"
    :"^1.2.4" ,"@vitejs/plugin-vue-jsx"
    :"^1.1.6" ,"@vue/compiler-sfc"
    :"^3.0.5" ,"eslint"
    :"^8.15.0" ,"eslint-config-prettier"
    :"^8.5.0" ,"eslint-config-standard"
    :"^17.0.0" ,"eslint-plugin-prettier"
    :"^4.0.0" ,"eslint-plugin-vue"
    :"^8.7.1" ,"husky"
    :"^8.0.1" ,"lint-staged"
    :"^12.4.1" ,"prettier"
    :"^2.6.2" ,"typescript"
    :"^4.3.2" ,"vite"
    :"^2.8.6" ,"vue-tsc"
    :"^0.33.9" }
  "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.js

.
module=exports // 设置我们的运行环境为浏览器 + es2021 + node ,否则eslint在遇到 Promise,window等全局对象时会报错 {
  env
  :browser {
    :true ,es2021
    :true ,node
    :true ,// 开启setup语法糖环境
    'vue/setup-compiler-macros'
    :true ,}
  ,// 继承eslint推荐的规则集,vue基本的规则集,typescript的规则集

  extends
  :[ 'plugin:vue/vue3-recommended'
    ,'plugin:@typescript-eslint/recommended'
    ,'standard'
    ,// 格式化规范 'plugin:prettier/recommended'
    ,// 新增,必须放在最后面,prettier规则覆盖与eslint冲突的规则 'prettier'
    ,// 避免vue 与 prettier冲突 'eslint:recommended'
    ,]
  ,// 定义ESLint的解析器

  parser
  :'vue-eslint-parser' ,// 支持ts的最新语法

  parserOptions
  :ecmaVersion {
    :'latest' ,parser
    :'@typescript-eslint/parser' ,sourceType
    :'module' ,}
  ,// 添加vue和@typescript-eslint插件,增强eslint的能力

  plugins
  :[ 'vue','@typescript-eslint' ,'prettier' ],rules

  :// "off"或者0    //关闭规则关闭 {
    // "warn"或者1    //在打开的规则作为警告(不影响退出代码)
    // "error"或者2    //把规则作为一个错误(退出代码触发时为1)
    'no-console'

    :. process.envNODE_ENV=== 'production' ? 'error' : 'off' ,'no-debugger'
    :. process.envNODE_ENV=== 'production' ? 'error' : 'off' ,// 解析vue模板错误规则
    'vue/no-parsing-error'
    :[ 2
      ,'x-invalid-end-tag'
      {
        :false ,'missing-semicolon-after-character-reference'
        :false ,}
      ,]
    ,'no-unused-expressions'
    :[ 'error',allowShortCircuit { :true ,allowTernary :true } ],// 允许使用短路、三目 'no-param-reassign'
    :[ 'error',props { :false } ],// 函数形参可修改 'vue/multi-word-component-names'
    :'off' ,// eslint-plugin-vue @8版本中新增了不少的规则,第一条就是 **‘vue/multi-word-component-names’: ‘error’,**所有index.vue 会报错,解决方法: 'no-new-object'
    :'off' ,// 关闭不可以new对象的规则 'no-explicit-any'
    :'off' ,// 可以使用any,但请尽量不使用any '@typescript-eslint/no-explicit-any'
    :'off' ,// ts可以使用any 'vue/v-on-event-hyphenation'
    :'off' ,// 关闭事件命名样式需要用连字符 }
  ,}
;// .prettierrc.js

/** 
  tips:
    endOfLine: 'crlf' 因为eslint和prettier就这个问题上不一致互相冲突,我们这里统一使用Windows系统的.
    如果是有mac使用需求的请使用git config --global core.autocrlf false解决
 */

.
module=exports printWidth {
  :100 ,//单行长度 tabWidth
  :2 ,//缩进长度 useTabs
  :false ,//使用空格代替tab缩进 semi
  :true ,//句末使用分号 singleQuote
  :true ,//使用单引号 endOfLine
  :'crlf' ,// Windows }
;// .vscode/settings.json



"editor.formatOnSave"
{
  :true ,"editor.defaultFormatter"
  :"esbenp.prettier-vscode" ,"editor.codeActionsOnSave"
  :"source.fixAll" {
    :true }
  }
// .husky/pre-commit

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

npx -no-install lintstaged
鸣谢

参考:

幕小白 项目中 Prettier + Stylelint + ESlint 配置
eslint-plugin-vue
羽徵 — Delete eslint(prettier/prettier) 错误的解决方案
羽墨 项目中 Prettier + Stylelint + ESlint 配置
Eslint与Prettier冲突解决,及eslint 问题记录

感谢各位开源作者

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/940217.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存