xDocxDoc
AI
前端
后端
iOS
Android
Flutter
AI
前端
后端
iOS
Android
Flutter
  • 关于

    • Prettier
    • 构建并强制执行
    • Prettier vs. Linters
    • 选项设计原理
    • 设计理念
  • 使用

    • 安装指南
    • 忽略代码
    • precommit
    • 插件
    • CLI
    • API
    • Browser
    • CI
  • 配置 Prettier

    • options
    • Configuration File
    • 共享配置
  • Editors

    • 编辑器集成
    • WebStorm 设置
    • Vim 配置指南
    • 监视文件变更
  • Misc

    • 技术实现细节
    • 生态
    • 企业解决方案

插件

插件是为 Prettier 添加新语言或格式化规则的方式。Prettier 自身所有语言的实现都基于插件 API。核心 prettier 包内置了 JavaScript 等 Web 相关语言的支持,其他语言需安装额外插件。

使用插件

加载方式:

  • CLI:通过 --plugin 参数

    prettier --write main.foo --plugin=prettier-plugin-foo

    提示

    支持多次设置 --plugin 选项

  • API:通过 plugins 选项

    await prettier.format("code", {
      parser: "foo",
      plugins: ["prettier-plugin-foo"],
    });
  • 配置文件:

    {
      "plugins": ["prettier-plugin-foo"]
    }

plugins 参数最终通过 https://nodejs.org/api/esm.html#import-expressions 解析,支持模块名/路径等格式。

官方插件

  • https://github.com/prettier/plugin-php
  • https://github.com/prettier/plugin-pug(由 https://github.com/Shinigami92 维护)
  • https://github.com/prettier/plugin-ruby
  • https://github.com/prettier/plugin-xml

社区插件

  • Apex 语言: https://github.com/dangmai/prettier-plugin-apex(@dangmai)
  • Astro 框架: https://github.com/withastro/prettier-plugin-astro(Astro 团队)
  • Elm 语言: https://github.com/gicentre/prettier-plugin-elm(@giCentre)
  • ERB 模板: https://github.com/adamzapasnik/prettier-plugin-erb(@adamzapasnik)
  • Gherkin 语法: https://github.com/mapado/prettier-plugin-gherkin(@mapado)
  • GLSL 着色器: https://github.com/NaridaL/glsl-language-toolkit/tree/main/packages/prettier-plugin-glsl(@NaridaL)
  • Go 模板: https://github.com/NiklasPor/prettier-plugin-go-template(@NiklasPor)
  • Java 语言: https://github.com/jhipster/prettier-java(JHipster)
  • Jinja 模板: https://github.com/davidodenwald/prettier-plugin-jinja-template(@davidodenwald)
  • JSONata 查询: https://github.com/Stedi/prettier-plugin-jsonata(Stedi)
  • Kotlin 语言: https://github.com/Angry-Potato/prettier-plugin-kotlin(@Angry-Potato)
  • Motoko 语言: https://github.com/dfinity/prettier-plugin-motoko(Dfinity)
  • Nginx 配置: https://github.com/joedeandev/prettier-plugin-nginx(@joedeandev)
  • Prisma 架构: https://github.com/umidbekk/prettier-plugin-prisma(@umidbekk)
  • Properties 文件: https://github.com/eemeli/prettier-plugin-properties(@eemeli)
  • Rust 语言: https://github.com/jinxdash/prettier-plugin-rust(@jinxdash)
  • Shell 脚本: https://github.com/un-ts/prettier/tree/master/packages/sh(@JounQin)
  • SQL 语言: https://github.com/un-ts/prettier/tree/master/packages/sql(@JounQin)
  • SQL-CST: https://github.com/nene/prettier-plugin-sql-cst(@nene)
  • Solidity 语言: https://github.com/prettier-solidity/prettier-plugin-solidity(@mattiaerre)
  • Svelte 框架: https://github.com/sveltejs/prettier-plugin-svelte(Svelte 团队)
  • TOML 配置: https://github.com/un-ts/prettier/tree/master/packages/toml(@JounQin & @so1ve)

开发插件

Prettier 插件需导出以下五个属性或默认导出包含这些属性的对象:

languages

定义插件支持的语言:

export const languages = [
  {
    name: "InterpretedDanceScript", // 语言名称
    parsers: ["dance-parse"],       // 使用的解析器
    // 其他支持信息字段(可选)
  }
];

parsers

实现代码字符串到https://en.wikipedia.org/wiki/Abstract_syntax_tree的转换:

export const parsers = {
  "dance-parse": {        // 与languages中的解析器名匹配
    parse,                // 核心解析函数
    astFormat: "dance-ast",// 生成的AST格式名称
    // 可选功能函数
    hasPragma,            // 检测特殊指令
    locStart,             // 获取节点起始位置
    preprocess            // AST预处理
  }
};

解析函数签名

function parse(text: string, options: object): Promise<AST> | AST;

printers

将AST转换为Prettier中间表示(Doc):

export const printers = {
  "dance-ast": {          // 与astFormat匹配
    print,                // 核心打印函数
    // 可选高级功能
    embed,                // 嵌入式语言处理
    getVisitorKeys,       // 控制AST遍历
    handleComments: {     // 注释处理策略
      ownLine, 
      endOfLine
    }
  }
};

打印流程

  1. AST预处理:调用preprocess(若定义)
  2. 注释挂载:自动或通过handleComments手动处理
  3. 嵌入式语言:通过embed异步处理
  4. 递归打印:通过print函数构建Doc树

核心打印函数

function print(
  path: AstPath,         // AST节点路径
  options: object,       // 全局配置
  print: Function        // 子节点打印回调
): Doc;

嵌入式语言处理

function embed(path, options) {
  if (path.node.type === "embedded-lang") {
    return async (textToDoc) => {
      // 调用其他解析器处理嵌入代码
      return await textToDoc(code, { parser: "target-parser" });
    };
  }
}

options

声明插件自定义配置项:

export const options = {
  customOption: {
    type: "boolean",
    default: true,
    description: "自定义配置说明"
  }
};

defaultOptions

覆盖Prettier核心选项默认值:

export const defaultOptions = {
  tabWidth: 4  // 修改默认缩进为4空格
};

工具函数

提供util-shared工具集:

// 常用工具示例
skipWhitespace(text, startIndex)  // 跳过空白字符
getStringWidth(text)              // 计算字符串显示宽度
makeString(rawText, quote)        // 安全构造引号字符串

测试插件

开发时可通过相对路径测试:

import prettier from "prettier";
const code = "(demo-code)";
await prettier.format(code, {
  parser: "custom-parser",
  plugins: ["."]  // 加载当前目录插件
});

教程资源

  • https://medium.com/@fvictorio/how-to-write-a-plugin-for-prettier-a0d98c845e70:TOML插件开发实战

总结

本文全面解析了 Prettier 插件生态系统的关键要素:

  1. 插件应用:详细说明 CLI/API/配置文件三种加载方式
  2. 生态资源:分类列出 20+ 官方/社区维护的语言插件
  3. 开发规范:系统阐述插件五大核心模块(语言定义、解析器、打印器、配置项、默认值覆盖)
  4. 关键技术:
    • AST 解析与转换机制
    • 嵌入式语言处理策略
    • 注释处理的三种模式(独立行/行尾/其他)
    • 自定义配置项声明规范
  5. 开发支持:提供调试方法、工具函数集和实战教程

插件通过实现标准接口扩展 Prettier 支持的语言范围,其架构采用模块化设计,核心在于解析器(文本→AST)和打印器(AST→格式化代码)的协同工作。开发者可重点关注 print 函数实现和 embed 异步处理机制,利用 util-shared 工具函数简化开发。

最后更新: 2025/8/26 10:07
Prev
precommit
Next
CLI