Code前端首页关于Code前端联系我们

Vue3项目里怎么搭配Prettier用?常见踩坑和最佳配置是啥?会不会和ESLint冲突怎么办?

terry 57分钟前 阅读数 21 #Vue

不管是刚入门前端项目搭建还是维护已久的Vue3项目,Prettier都是绕不开的代码格式化工具,但很多开发者要么只会复制粘贴网上的旧配置,要么对它和ESLint、Vetur/Volar的关系搞不清,要么遇到代码改完就报错,踩了一堆小坑还没找到顺手的一套东西,今天就从大家最关心的几个问题,用最实用的方式,把Vue3搭配Prettier的全流程、避坑指南、最佳配置都讲清楚。

第一步:基础的Vue3+Prettier项目搭建流程

不管你是用Vite还是Vue CLI新建项目,或者是给老项目补装,流程其实不难,但很多细节不能省。

用Vite新建项目时的快捷初始化

如果你刚开新项目,强烈建议直接在Vite的引导界面选对工具链集成插件,一步到位搞定基础配置,启动Vite的引导的话,输入npm create vite@latest my-vue3-prettier-app -- --template vue或者pnpm/yarn create vite my-vue3-prettier-app --template vue都行,进去后记得按提示选“Add Prettier for code formatting?”这个选项,选“是”之后Vite会自动帮你安装好prettier这个核心依赖,还会在项目根目录生成一个默认的.prettierrc.json文件和.prettierignore文件。

但这里有个小问题,Vite默认给Vue3生成的模板用的是单文件组件对吧?默认的.prettierrc.json会不会对.vue文件的支持不够?别着急,后面的最佳配置里会加。

给已有的Vue3项目补装Prettier

如果是老项目,那得自己动手一步步来,首先肯定是安装依赖,这里推荐局部安装,这样团队协作的时候,大家的Prettier版本能统一,不会因为各自用全局的不同版本导致格式不一样,安装命令分三种包管理器都给你列出来,选你常用的就行:npm的话是npm install -D prettier,pnpm是pnpm add -D prettier,yarn是yarn add -D prettier --exact——哦对了,yarn这里加个--exact锁定版本号的后缀更好,避免自动升级小版本的话有时候会有小变动,比如引号规则微调导致不必要的git diff。

安装完核心依赖,还得补装一个专门支持Vue单文件组件的Prettier插件?不对不对,现在Prettier 3.x版本已经内置对.vue的解析了?等下等下,等下回忆下:Prettier 2.6版本开始就内置了Vue SFC的解析,但Volar/Vetur可能会有兼容性?或者解析的选项?哦不对,解析器还是可以手动指定的,但先别急,先讲基础文件。

接下来创建配置文件,根目录下可以建.prettierrc.json.prettierrc.js.prettierrc.cjs.prettierrc.toml这些,还有.editorconfig要不要?对哦,很多编辑器如果开启了EditorConfig的话,会覆盖部分Prettier的规则,比如缩进、换行符这些,所以最好先把EditorConfig和Prettier统一一下,避免冲突。

`.editorconfig的内容先放个通用的给你,不管是Windows还是Mac/Linux,统一换行符用LF,缩进用2个空格,UTF-8编码,没有尾空格这些:

root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

然后是基础的.prettierrc.json,这里先不写Vue相关的,等下最佳配置一起整合:

{}

哦不对不对,基础配置里可以先加个默认的,至少让它跑起来,比如先加个vue文件对应的,哦不对,刚才说的内置解析器,那.prettierignore是必须的,别让它格式化node_modules、dist这些,还有其他不需要的文件,env.local这些:

node_modules
dist
dist-ssr
*.local
.DS_Store
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

然后是package.json里加个格式化的脚本,方便大家统一用,比如"format": "prettier --write src/",或者再加个检查格式的,用来在CI/CD里跑,比如"format:check": "prettier --check src/",这样提交代码前可以先format检查,如果不符合的话会直接写死不通过,保证代码库的格式统一。

最后还要注意,如果你用的是Vue CLI 5.x,默认也有快捷初始化的方式吗?有的,输入vue create my-vue3-prettier-app的时候,也会有工具链的选项,选Prettier就行,不过Vue CLI现在用的人好像没Vite多了,但不管是啥,基础流程都是补依赖、写配置、加ignore、加脚本这几步。

第二步:Vue3搭配Prettier的最佳配置

刚才说了,Vite或者Vue CLI默认给的配置可能不够,或者不符合国内前端团队的开发习惯,所以得调整一下,这里的最佳配置是结合了Vue官方推荐、Prettier官方文档,还有很多大厂前端团队的公开配置总结出来的,当然你可以根据自己的习惯微调,但这些核心建议最好保留,避免后面踩坑。

第一步:补充Prettier的通用配置

通用配置是不管是.js、.ts、.css、.json,还是.vue文件都会生效的,先看.prettierrc.js为什么推荐用.js而不是.json呢?因为.js可以写注释,还可以用条件判断(虽然一般不需要),对团队协作的时候,写注释说明每个规则是干嘛的,新人接手的时候一眼就能看懂,不会乱改。

module.exports = {
  // 每行最多多少个字符换行,一般80或者100?看团队习惯,大厂一般100
  printWidth: 100,
  // 用2个空格缩进,别用4个,Vue单文件组件缩进太多会横向滚动条拉很长
  tabWidth: 2,
  // 不用tab用空格
  useTabs: false,
  // 语句末尾要不要加分号?很多人纠结这个,选true吧,不会有自动分号插入的坑
  semi: true,
  // 字符串用单引号还是双引号?国内团队很多用单引号,除非转义
  singleQuote: true,
  // 对象的属性要不要加引号?选as-needed,就是只有属性名里有特殊字符才加
  quoteProps: 'as-needed',
  // JSX的属性用单引号还是双引号?和上面一样
  jsxSingleQuote: true,
  // 最后一个元素后面要不要加逗号?选es5,就是数组、对象、函数参数这些最后一个加,方便git diff
  trailingComma: 'es5',
  // 对象字面量的大括号之间要不要加空格?选true, a: 1 }而不是{a:1}
  bracketSpacing: true,
  // JSX的标签闭合尖括号要不要换行?选false,lt;button onClick={handleClick}>而不是<button
  //  onClick={handleClick}
  // >
  bracketSameLine: false,
  // 箭头函数参数只有一个的时候要不要加括号?选always,避免歧义
  arrowParens: 'always',
  // 换行符用LF,和.editorconfig统一
  endOfLine: 'lf',
  // 要不要保留HTML的空白?选ignore,因为HTML的空白有时候是有用的
  htmlWhitespaceSensitivity: 'ignore',
  // Vue单文件组件的script和style标签里的内容要不要缩进?选true,看起来更整齐
  vueIndentScriptAndStyle: true,
  // 要不要格式化嵌入在markdown里的代码块?选auto
  embeddedLanguageFormatting: 'auto',
  // 要不要格式化引号里的换行?选preserve
  proseWrap: 'preserve',
};

这里重点说几个针对Vue单文件组件的vueIndentScriptAndStyle这个规则,Prettier 2.6版本之前是没有的,那时候得装prettier-plugin-vue`插件,但3.x版本之后内置了,而且这个规则,选true的话,script和style标签里的内容会有2个空格的缩进,看起来和template标签对齐,不会像Vetur默认那样缩进4个或者不缩进,强迫症看着舒服。

还有htmlWhitespaceSensitivity这个规则,选ignore的话,Prettier会把HTML标签里的多余空白去掉,比如<div> 测试 </div>会变成<div>测试</div>,但不会影响flex或者inline-block这些布局,因为多余的空白节点在布局里有时候会有间隙,选ignore的话,Prettier会在处理的时候,会自动把两个块级标签之间的空白保留,把inline标签之间的多余空白去掉,不会有布局问题,这个规则是Vue官方文档推荐的。

第二步:要不要装Prettier和Volar/Vetur的插件?

哦对,编辑器里的自动格式化,不能只靠npm run format命令,还要让编辑器在保存的时候自动格式化,这样写代码的时候更爽,不管是VS Code还是WebStorm,都得装对应的Prettier插件,VS Code里直接搜Prettier - Code formatter,WebStorm里设置里搜Prettier然后启用就行。

然后重点来了,Vue3现在官方推荐的编辑器插件是Volar对吧?不是Vetur了,Vetur主要是给Vue2用的,不过Vue3也能用,但兼容性不如Volar好,而且Volar现在也有Vue2的版本叫Volar.js,那Volar和Prettier怎么配合?VS Code里,Volar默认会提供一些格式化的规则,比如template标签里的HTML格式化,这时候就会有个优先级的问题,到底是用Volar的格式化还是Prettier的格式化?

强烈建议禁用Vetur(如果你用的是Vue3),然后在VS Code的设置里,把默认的格式化工具改成Prettier,然后针对.vue文件也单独指定用Prettier格式化,这样就不会有两个格式化工具打架的情况了,VS Code的设置可以在根目录下建个.vscode/settings.json文件,这样团队协作的时候大家的编辑器设置也能统一,不用每个人自己调,这个太重要了,很多人忘记这一步,导致每个人保存的时候格式不一样。

.vscode/settings.json放个通用的给你:

{
  // 禁用Vetur,因为用Volar
  "vetur.validation.template": false,
  "vetur.format.enable": false,
  // 默认的格式化工具用Prettier
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  // 保存的时候自动格式化
  "editor.formatOnSave": true,
  // 粘贴的时候自动格式化
  "editor.formatOnPaste": true,
  // 打字的时候自动格式化(可选,看习惯)
  "editor.formatOnType": false,
  // 针对Vue单文件组件单独指定格式化工具
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 针对JavaScript文件单独指定格式化工具
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 针对TypeScript文件单独指定格式化工具
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 针对CSS/SCSS/LESS文件单独指定格式化工具
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[less]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 针对JSON文件单独指定格式化工具
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 针对HTML文件单独指定格式化工具
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // Volar的一些设置,让它和Prettier配合更好
  "vue.completion.autoImportComponent": true,
  "vue.inlayHints.missingProps": true,
  "vue.inlayHints.inlineHandlerLeading": true
};

WebStorm的话,设置里搜Prettier,然后勾选“Run on save for files”,然后把.vue.js.ts这些文件都加进去,然后在设置里搜Vue,把Vetur的插件禁用,把Volar的启用就行。

第三步:Prettier和ESLint的冲突怎么解决?

这个是Vue3项目里最常碰到的踩坑点了!很多人刚装完Prettier和ESLint,保存的时候要么代码被Prettier改完ESLint就报错,要么被ESLint fix完Prettier又觉得不对,来回拉扯,特别闹心。

首先得搞清楚Prettier和ESLint的分工:Prettier只负责代码的格式化,比如缩进、换行、引号、分号这些;ESLint负责代码的质量检查,比如变量有没有定义、有没有用console.log、有没有多余的逗号这些(哦不对ESLint其实也有一些格式化的规则),所以冲突的根源就是ESLint里的格式化规则和Prettier的格式化规则重复或者不一样。

那怎么解决呢?有两个方案,一个是“Prettier先格式化,然后ESLint再检查并修复质量问题”,另一个是“让ESLint完全不处理格式化规则,全部交给Prettier”,强烈推荐第二个方案,因为这个方案更简单,更不容易有冲突,而且也是Vue官方文档推荐的。

第二个方案的具体步骤是:安装两个插件,一个是eslint-config-prettier,用来禁用ESLint里和Prettier重复或者冲突的格式化规则;另一个是eslint-plugin-prettier,用来把Prettier的规则作为ESLint的规则来检查,这样就可以用ESLint --fix来同时修复Prettier的格式问题和ESLint的质量问题了,一步到位,特别爽。

不管是Vite还是Vue CLI新建的项目,如果刚才选了集成ESLint和Prettier的话,会不会自动装这两个插件?Vite好像不会,Vue CLI好像会,但不管会不会,自己动手确认一下或者补装一下更保险,安装命令还是分三种包管理器:npm是npm install -D eslint-config-prettier eslint-plugin-prettier,pnpm是pnpm add -D eslint-config-prettier eslint-plugin-prettier,yarn是yarn add -D eslint-config-prettier eslint-plugin-prettier --exact

接下来修改ESLint的配置文件,根目录下的ESLint配置文件一般是.eslintrc.cjs(因为Vite和Vue CLI 5.x都是用的CommonJS模块)或者.eslintrc.js或者.eslintrc.json,推荐用.eslintrc.cjs或者.js,可以写注释。

修改的方法很简单,在extends数组里,先加eslint-config-prettier,然后再加eslint-plugin-prettier/recommended,注意顺序很重要,后面的extends会覆盖前面的,所以必须把eslint-config-prettier放在前面,把eslint-plugin-prettier/recommended放在最后,这样才能确保Prettier的规则生效,并且禁用ESLint的格式化规则。

比如用Vite新建的Vue3+TypeScript+ESLint的项目,默认的.eslintrc.cjs是这样的:

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution');
module.exports = {
  root: true,
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-typescript',
  ],
  parserOptions: {
    ecmaVersion: 'latest',
  },
};

修改后的.eslintrc.cjs是这样的:

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution');
module.exports = {
  root: true,
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-typescript',
    // 先加eslint-config-prettier,禁用ESLint里和Prettier重复的格式化规则
    'eslint-config-prettier',
    // 再加eslint-plugin-prettier/recommended,把Prettier的规则作为ESLint的规则来检查
    'plugin:prettier/recommended',
  ],
  parserOptions: {
    ecmaVersion: 'latest',
  },
  rules: {
    // 这里可以加你自己的ESLint质量检查规则,比如禁用console.log,但允许console.error
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    // 禁用未使用的变量,但允许以_开头的变量
    'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
    '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
    // 允许v-html,不过生产环境要注意安全
    'vue/no-v-html': 'off',
  },
};

这里重点说一下plugin:prettier/recommended,它其实相当于同时做了三件事:第一,把prettier作为ESLint的插件;第二,把prettier的规则作为ESLint的规则来检查;第三,把prettier的规则的严重程度设为error或者warn?默认是error,但你可以自己在rules里改,比如'prettier/prettier': 'warn',这样不符合Prettier的规则只会提示不会报错。

然后还要修改package.json里的脚本,把原来的lintformat合并成一个,或者保留两个,比如保留lint用来检查并修复质量和格式问题,保留format用来只修复格式问题,CI/CD里可以先跑format:check再跑lint:check,或者直接跑lint:check,因为plugin:prettier/recommended已经把Prettier的规则加进去了,修改后的脚本大概是这样的:

{
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
    "lint:check": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

哦对了,这里的lint脚本里的路径用了,而不是src/,这样会检查整个项目的文件,包括根目录下的配置文件,不过记得把.eslintignore文件写好,别让它检查node_modules、dist这些,和.prettierignore差不多:

node_modules
dist
dist-ssr
*.local
.DS_Store
.vscode/*
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

最后还要确认一下VS Code的设置里,有没有开启保存的时候自动修复ESLint的问题,这样可以和保存的时候自动格式化配合起来,一步到位,在.vscode/settings.json里加这两行:

{
  // 保存的时候自动修复ESLint的问题
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  // 禁用保存的时候自动格式化,因为ESLint已经会自动修复Prettier的格式问题了,避免重复格式化
  "editor.formatOnSave": false
}

哦对哦,这里有个重要的调整:刚才在前面的通用设置里开了editor.formatOnSave: true,现在因为用了eslint-plugin-prettier,可以把editor.formatOnSave改成false,然后只开source.fixAll.eslint: true,这样保存的时候只会用ESLint来同时修复质量和格式问题,不会有重复格式化的情况,这个细节很多人踩坑!

第四步:常见的Vue3+Prettier踩坑点总结

刚才讲了全流程和最佳配置,现在再总结几个最常见的踩坑点,帮你提前避坑:

踩坑点1:Vetur和Volar同时启用,导致格式化冲突

这个刚才已经说过了,Vue3一定要禁用Vetur,只用Volar,而且要确保VS Code里把默认的格式化工具改成Prettier或者让ESLint来修复。

踩坑点2:Prettier的版本是3.x,但是用了旧的prettier-plugin-vue插件

Prettier 3.x版本已经内置了对Vue单文件组件的解析了,不需要再装prettier-plugin-vue插件,装了反而会有兼容性问题,比如vueIndentScriptAndStyle这个规则失效,或者直接报错说找不到解析器。

踩坑点3:EditorConfig和Prettier的规则冲突

比如EditorConfig里设置了indent_size: 4,但是Prettier里设置了tabWidth: 2,这时候很多编辑器会优先用EditorConfig的规则,导致格式化出来的代码是4个空格缩进,而不是2个,所以一定要把EditorConfig和Prettier的规则统一起来。

踩坑点4:单文件组件里的script和style标签不缩进

这个刚才也说过了,在Prettier的配置里加vueIndentScriptAndStyle: true就行,而且这个规则只在Prettier 2.6及以上版本才有,所以要确保Prettier的版本不低于2.6,推荐用最新的稳定版3.x。

踩坑点5:ESLint和Prettier的extends顺序不对

刚才也说过了,extends数组里的顺序很重要,必须把eslint-config-prettier放在前面,把plugin:prettier/recommended放在最后,这样才能确保Prettier的规则生效,并且禁用ESLint的格式化规则。

踩坑点6:忽略了环境变量或者其他配置文件

比如.env.env.local.vscode/settings.json这些文件,记得加到.prettierignore.eslintignore里,不然Prettier和ESLint会去格式化或者检查这些文件,导致不必要的git diff或者报错。

踩坑点7:全局安装了Prettier,版本和项目里的局部版本不一样

这个刚才也说过了,一定要局部安装Prettier,并且加--exact锁定版本号,这样团队协作的时候,大家的Prettier版本能统一,不会因为各自用全局的不同版本导致格式不一样。

第五步:团队协作的注意事项

刚才讲了很多单个开发者的配置,现在再讲几个团队协作的注意事项,这样整个团队的代码格式才能完全统一,不会有git diff里全是格式改动的情况:

注意事项1:把所有的配置文件都提交到git仓库里

包括.prettierrc.js.prettierignore.editorconfig.eslintrc.cjs.eslintignore.vscode/settings.json这些,这样每个团队成员clone下来项目,不需要自己调配置,直接就能用。

注意事项2:在package.json里加engines字段

用来指定项目要求的Node.js版本和包管理器版本,这样可以避免因为Node.js版本或者包管理器版本不一样导致依赖安装失败或者格式不一样。

{
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0",
    "pnpm": ">=8.0.0",
    "yarn": ">=1.22.0"
  }
}

注意事项3:用git hooks来在提交代码前自动检查和修复格式问题

比如用husky和lint-staged这两个工具,husky用来管理git hooks,lint-staged用来只检查和修复暂存区的文件,这样提交代码前会自动跑format和lint,避免不符合格式的代码提交到git仓库里。

安装husky和lint-staged的步骤很简单,先装husky:npm install -D husky或者pnpm add -D husky或者yarn add -D husky --exact,然后启用husky:npx husky install或者pnpm husky install或者yarn husky install,然后在package.json里加个脚本:"prepare": "husky install",这样别人clone下来项目,npm install的时候会自动启用husky,然后装lint-staged:npm install -D lint-staged或者pnpm add -D lint-staged或者yarn add -D lint-staged --exact,然后在package.json里加个lint-staged字段:

{
  "lint-staged": {
    "*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss,less,json,jsonc,html,md}": [
      "prettier --write"
    ]
  }
}

然后创建一个pre-commit的git hook:npx husky add .husky/pre-commit "npx lint-staged"或者pnpm husky add .husky/pre-commit "pnpm lint-staged"或者yarn husky add .husky/pre-commit "yarn lint-staged",这样每次提交代码前,会自动检查和修复暂存区的文件,不符合的话会直接阻止提交,要求你改好才能提交。

注意事项4:在CI/CD里加format:check和lint:check

比如用GitHub Actions、GitLab CI/CD这些,在提交代码到远程仓库或者合并PR的时候,自动跑format:check和lint:check,这样可以避免不符合格式的代码合并到主分支里。

好了,今天的内容就讲到这里了,从基础的项目搭建,到最佳配置,到冲突解决,到踩坑点总结,到团队协作的注意事项,全流程都讲清楚了,相信你看完之后,肯定能在Vue3项目里顺利的搭配Prettier用了,再也不会踩那些常见的小坑了,如果还有其他问题的话,可以在评论区里留言,我们一起讨论。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门