likes
comments
collection
share

记一次vue@cli创建项目prettier失效

作者站长头像
站长
· 阅读数 42

最近在学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

我当时是选择了eslintprettier配置,最后会生成对应的配置文件,这里就只关心一下.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插件

记一次vue@cli创建项目prettier失效

对应的eslintprettier插件都有安装,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创建项目prettier失效

排查

为什么会这样,我修改了vue@cli创建项目的好多配置,主要排查对象放在eslintvscode编辑器上,甚至重新安装相关依赖,不使用脚手架提供的,还是没有发现问题。

吃完饭后无意中发现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格式化。

但我们日常开发中,通常都是prettiereslint都是一起使用的,如果要想单独使用某一个的话,skip-formatting参数应该是根据用户是否在prettiereslint二选一的时候决定,也不知道这样做是为了什么。

解决

最后的解决办法就很简单

  1. 不使用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'
  },
}


  1. 这个文件不是吧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
评论
请登录