singleQuote 配置踩坑记:Prettier 与 ESLint 冲突的终极解决方案

利利(打工版) 工具 阅读 1,430
赞 92 收藏
二维码
手机扫码查看
反馈

先上代码:这玩意儿到底怎么用

别整那些虚的,直接看代码最实在。我在项目里折腾 singleQuote 这个配置项,其实主要是在 Prettier 里用的。很多人以为它只是“单引号还是双引号”的问题,但实际用起来才发现,坑不少,细节更多。

singleQuote 配置踩坑记:Prettier 与 ESLint 冲突的终极解决方案

先说最基础的配置。在你的 .prettierrc 文件里加上这一行:

{
  "singleQuote": true
}

搞定,从此你写的 JS/TS 里字符串默认就用单引号了。比如:

const msg = 'Hello, world!';

而不是:

const msg = "Hello, world!";

看起来很简单对吧?但问题来了——不是所有地方都认这个配置。我一开始以为配完就万事大吉,结果在写 HTML 模板字符串或者 JSX 的时候,发现双引号还在乱跑。

这个场景最好用:JSX + 单引号 = 清爽

如果你用 React,那 singleQuote: true 简直是救星。因为 JSX 属性默认用双引号,而 JS 字符串如果也用双引号,嵌套起来特别难受:

// 双引号地狱(没开 singleQuote)
const element = <div className="container" data-msg="It's a "test"">Content</div>;

开了之后:

// 单引号清爽多了
const element = <div className="container" data-msg='It's a "test"'>Content</div>;

虽然属性值还是双引号(Prettier 默认 JSX 属性用双引号),但 JS 字符串变成单引号后,混用时转义少很多。亲测有效,代码可读性提升明显。

不过注意:Prettier 对 JSX 属性的引号有单独控制项——jsxSingleQuote。如果你连属性都想用单引号,得额外加:

{
  "singleQuote": true,
  "jsxSingleQuote": true
}

这时候 JSX 也会变成:

const element = <div className='container' data-msg='It's a "test"'>Content</div>;

但我个人不推荐这么干。为啥?因为 HTML 世界默认是双引号,很多工具链(比如 ESLint 的 jsx-quotes 规则)默认也期望双引号。强行全单引号反而容易和团队规范冲突。所以我只开 singleQuote,不动 jsxSingleQuote

踩坑提醒:这三点一定注意

下面这三个坑,我至少踩过两次,尤其是第三点,折腾了半小时才搞明白。

  • 1. 配置文件格式影响解析:如果你用的是 .prettierrc.js 而不是 JSON,记得导出对象,别漏了引号本身是不是被转义了。曾经有个同事写成 module.exports = { singleQuote: "true" },结果字符串 "true" 被当成真值,但类型不对,Prettier 直接忽略,行为异常。
  • 2. VS Code 插件缓存问题:改完配置后,有时候格式化没生效。别急着重启编辑器,先试试:Ctrl+Shift+P → 输入 “Prettier: Restart Server”。亲测比重启快多了。
  • 3. 和 ESLint 冲突时,谁说了算? 这是最头疼的。如果你同时用了 eslint-config-prettier + @typescript-eslint,要确保 ESLint 不再管引号规则。比如关闭 quotes 规则:
    // .eslintrc.js
        rules: {
          // 关掉 ESLint 的 quotes,交给 Prettier 处理
          quotes: "off",
          "@typescript-eslint/quotes": "off"
        }

    否则你会看到保存时格式化一次,ESLint 又改回去,来回拉扯,气死人。

高级技巧:配合 Git Hooks 自动统一

光自己用还不够,得让整个团队都统一。我的做法是:在 lint-staged 里加一行,提交代码前自动格式化。

先装依赖:

npm install --save-dev lint-staged prettier

然后在 package.json 里配:

{
  "lint-staged": {
    "*.{js,ts,jsx,tsx}": "prettier --write"
  }
}

再配合 Husky 的 pre-commit hook,每次提交都会强制走 Prettier。这样就算有人本地没装插件,也不会污染代码库的引号风格。

不过这里有个小瑕疵:如果某人写了带双引号的字符串,又没开 singleQuote,提交时会被自动改成单引号。如果他本地没跑过格式化,下次 pull 代码可能会有冲突。所以团队必须提前对齐配置,最好把 .prettierrc 提交到仓库根目录。

还有哪些地方会受影响?

除了 JS/TS,Prettier 的 singleQuote 还会影响这些文件:

  • JSON5(但标准 JSON 不支持单引号,所以不会改)
  • Vue SFC 中的 script 块
  • Svelte 的 JS 部分
  • Markdown 里的代码块(仅当语言是 JS/TS 时)

但注意:CSS、HTML、纯 JSON 文件不受影响。比如你在 HTML 里写:

<div data-msg='hello'></div>

Prettier 不会把它改成双引号,因为 HTML 不归 singleQuote 管。这点很多人误解,以为开了就全局单引号,其实不是。

另外,如果你在 JS 里写模板字符串,比如:

const html = &lt;div class=&quot;box&quot;&gt;Content&lt;/div&gt;;

里面的双引号不会被改成单引号,因为模板字符串内部 Prettier 默认不处理引号类型(除非你用了像 prettier-plugin-organize-attributes 这种插件)。所以别指望它能自动优化 HTML 片段里的引号。

结尾:简单但值得深挖

singleQuote 看似是个小配置,但牵扯到编辑器、格式化工具、lint 工具、团队协作多个环节。我见过太多项目因为引号风格不统一,PR 里全是无意义的 diff,浪费 review 时间。

建议:新项目直接开 singleQuote: true,老项目评估迁移成本后再决定。反正我是回不去了——单引号写起来真的更顺手,尤其配合反引号模板字符串的时候。

以上是我踩坑后的总结,希望对你有帮助。这个技巧的拓展用法还有很多(比如结合自定义 Prettier 插件处理特殊 DSL),后续会继续分享这类博客。有更优的实现方式欢迎评论区交流。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论