记一次vue@cli创建项目prettier失效
最近在学vue3,使用vue@cli
创建项目的时候突然发现prettier
失效。各种上网查资料,修改vscode配置操作都不行。后来开两个项目,一个使用vue@cli
一个手动创建,发现使用vue@cli
创建的项目就是存在失效的问题,排查了很久才发现是官方配置问题,可以查看我提的issues
vue@cli创建项目
Vue3支持用vue@cli
创建项目,但前提是vue@cli
版本要在5.x以上,4.x的版本升级一下就可以。
创建项目
npm init vue@last
这一指令将会安装并执行 create-vue
,它是 Vue 官方的项目脚手架工具。你将会看到一些诸如 TypeScript 和测试支持之类的可选功能提示:
✔ Project name: … <your-project-name> // 项目名称
✔ Add TypeScript? … No / Yes // 添加ts
✔ Add JSX Support? … No / Yes // 添加jsx支持
✔ Add Vue Router for Single Page Application development? … No / Yes // 添加 router
✔ Add Pinia for state management? … No / Yes // 添加 Pinia
✔ Add Vitest for Unit testing? … No / Yes // 添加 vitest
✔ Add an End-to-End Testing Solution? … No / Cypress / Playwright // 添加端到端测试
✔ Add ESLint for code quality? … No / Yes // 添加Eslit
✔ Add Prettier for code formatting? … No / Yes // 添加Prettier
按照自己的需求选择完之后
cd vue-project2
npm install
npm run dev
我当时是选择了eslint
和prettier
配置,最后会生成对应的配置文件,这里就只关心一下.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',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
}
}
问题
由于是vue3项目,我直接把vetur
插件禁用掉,使用volar
插件
对应的eslint
、prettier
插件都有安装,VsCode自动保存修复也打开。
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true
}
然后修改一下代码,测试一下prettier
功能。
<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue';
</script>
<template>
<header>
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
<div class="wrapper">
<HelloWorld msg="You did it!" />
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
</div>
</header>
<RouterView />
</template>
很容易发现代码会有几个错误在里面,相同的代码我放在一个prettier
功能完好的项目里面就发现错误。
排查
为什么会这样,我修改了vue@cli
创建项目的好多配置,主要排查对象放在eslint
、vscode编辑器
上,甚至重新安装相关依赖,不使用脚手架提供的,还是没有发现问题。
吃完饭后无意中发现eslint
的一个配置后面加了skip-formatting
,为啥要跳过配置?然后把这个选项移除,惊奇的发现可以用了。
/* 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',
- '@vue/eslint-config-prettier/skip-formatting'
+ '@vue/eslint-config-prettier'
],
parserOptions: {
ecmaVersion: 'latest'
},
}
然后查看这个包文件,skip-formatting
到底是什么意思?它在node_modules/@vue/eslint-config-prettier/skip-formatting.js
module.exports = {
extends: [require.resolve("./index.js")],
rules: {
"prettier/prettier": "off",
},
};
有一个很关键的代码"prettier/prettier": "off",
它把prettier
关闭了,为什么要关闭这个配置呢,百思不得其解,然后去查阅Vue
仓库下的create-vue相关代码,发现官方用的是另外一个eslint
配置仓库create-eslint-config
import * as fs from 'node:fs'
import * as path from 'node:path'
import type { Linter } from 'eslint'
import createESLintConfig from '@vue/create-eslint-config' // create-eslint-config项目
...
const { pkg, files } = createESLintConfig({
vueVersion: '3.x',
// we currently don't support other style guides
styleGuide: 'default',
hasTypeScript: needsTypeScript,
needsPrettier, // needsPrettier参数从脚手架配置命令行参数里面获取
additionalConfig,
additionalDependencies
})
...
查看一下create-eslint-config
项目里面的相关代码
// This is also used in `create-vue`
export default function createConfig ({
vueVersion = '3.x', // '2.x' | '3.x' (TODO: 2.7 / vue-demi)
styleGuide = 'default', // default | airbnb | typescript
hasTypeScript = false, // js | ts
needsPrettier = false, // true | false
additionalConfig = {}, // e.g. Cypress, createAliasSetting for Airbnb, etc.
additionalDependencies = {} // e.g. eslint-plugin-cypress
}) {
// This is the pkg object to extend
const pkg = { devDependencies: {} }
const addDependency = (name) => {
pkg.devDependencies[name] = versionMap[name]
}
deepMerge(pkg.devDependencies, additionalDependencies)
deepMerge(eslintConfig, additionalConfig)
if (needsPrettier) {
addDependency('prettier')
addDependency('@vue/eslint-config-prettier')
eslintConfig.extends.push('@vue/eslint-config-prettier/skip-formatting') // 这里往eslint的extend属性里面添加了配置
}
const files = {
'.eslintrc.cjs': ''
}
...
就是这行eslintConfig.extends.push('@vue/eslint-config-prettier/skip-formatting')
它添加的是配置里面对应的skip-formatting
配置,也就是关掉prettier
那个。
在这个commit里面,作者重构了这个配置,目的是为了使用prettier
时,不使用eslint
格式化。
但我们日常开发中,通常都是prettier
和eslint
都是一起使用的,如果要想单独使用某一个的话,skip-formatting
参数应该是根据用户是否在prettier
和eslint
二选一的时候决定,也不知道这样做是为了什么。
解决
最后的解决办法就很简单
- 不使用
skip-formatting
这个配置文件
/* 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',
- '@vue/eslint-config-prettier/skip-formatting'
+ '@vue/eslint-config-prettier'
],
parserOptions: {
ecmaVersion: 'latest'
},
}
- 这个文件不是吧
prettier
给关掉了吗,我们打开就行。
/* 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',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
},
+ rules: {
+ 'prettier/prettier': 'error'
+ }
}
转载自:https://juejin.cn/post/7239282069750186041