0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事はVim駅伝の2026-07-08の記事です。
Vim駅伝は常に参加者を募集しています。詳しくはこちらのページをご覧ください。

今回は、Conform 導入済みの前提で、Biome / Prettier を条件付きで共存させる設定をまとめます。

1. 前提(Conform導入済み)

stevearc/conform.nvim はすでに入っている前提。
ここでは formatter の「条件」と「実行順」だけを調整します。

2. Biome側の設定(nvim/lua/plugins/biome.lua

---@alias ConformCtx {buf: number, filename: string, dirname: string}

local supported = {
  "css",
  "graphql",
  "javascript",
  "javascriptreact",
  "json",
  "jsonc",
  "typescript",
  "typescriptreact",
}

local function has_biome_config(ctx)
  return vim.fs.find("biome.json", { path = ctx.dirname, upward = true })[1] ~= nil
end

return {
  {
    "stevearc/conform.nvim",
    optional = true,
    opts = function(_, opts)
      opts.formatters_by_ft = opts.formatters_by_ft or {}
      for _, ft in ipairs(supported) do
        opts.formatters_by_ft[ft] = opts.formatters_by_ft[ft] or {}
        table.insert(opts.formatters_by_ft[ft], 1, "biome")
      end
      opts.formatters = opts.formatters or {}
      opts.formatters.biome = {
        condition = function(_, ctx)
          return has_biome_config(ctx)
        end,
      }
    end,
  },
}

ポイントは、biome を先頭に入れつつ、biome.json がある時だけ有効化している点。

3. Prettier側の設定(nvim/lua/plugins/prettier.lua

---@alias ConformCtx {buf: number, filename: string, dirname: string}
local M = {}

local supported = {
  "css","graphql","handlebars","html","javascript","javascriptreact","json","jsonc",
  "less","markdown","markdown.mdx","scss","typescript","typescriptreact","vue","yaml",
}

local config_names = {
  ".prettierrc",".prettierrc.json",".prettierrc.json5",".prettierrc.yml",".prettierrc.yaml",
  ".prettierrc.js",".prettierrc.cjs",".prettierrc.mjs",".prettierrc.toml",
  "prettier.config.js","prettier.config.cjs","prettier.config.mjs",
  "prettier.config.ts","prettier.config.cts","prettier.config.mts",
}

local function memoize(fn)
  local cache = {}
  return function(ctx)
    local key = ctx.filename
    if cache[key] == nil then
      cache[key] = fn(ctx)
    end
    return cache[key]
  end
end

function M.has_local_prettier(ctx)
  return vim.fs.find("node_modules/.bin/prettier", { path = ctx.dirname, upward = true })[1] ~= nil
end

function M.has_config(ctx)
  return vim.fs.find(config_names, { path = ctx.dirname, upward = true })[1] ~= nil
end

function M.has_parser(ctx)
  local ft = vim.bo[ctx.buf].filetype
  return vim.tbl_contains(supported, ft)
end

M.has_local_prettier = memoize(M.has_local_prettier)
M.has_config = memoize(M.has_config)
M.has_parser = memoize(M.has_parser)

return {
  {
    "stevearc/conform.nvim",
    optional = true,
    opts = function(_, opts)
      opts.formatters_by_ft = opts.formatters_by_ft or {}
      for _, ft in ipairs(supported) do
        opts.formatters_by_ft[ft] = opts.formatters_by_ft[ft] or {}
        table.insert(opts.formatters_by_ft[ft], "prettier")
      end
      opts.formatters = opts.formatters or {}
      opts.formatters.prettier = {
        condition = function(_, ctx)
          return M.has_local_prettier(ctx) and M.has_config(ctx) and M.has_parser(ctx)
        end,
      }
    end,
  },
}

こちらは「ローカル Prettier がある」「Prettier 設定がある」「対象 filetype」の3条件を満たす時だけ動きます。

4. どう動くか(4パターン)

  1. biome.json あり / Prettier条件なし → Biomeのみ
  2. biome.json なし / Prettier条件あり → Prettierのみ
  3. 両方条件あり → Biome → Prettier の順で実行され得る
  4. 両方条件なし → どちらも実行されない

5. 注意点(monorepoで両方走る可能性)

vim.fs.find(..., { upward = true }) なので、workspace ルートに biome.json と Prettier 設定が共存していると、配下の複数パッケージで 両方 true になりやすいです。
その場合、意図せず両方走ることがあります。

6. まとめ(必要なら排他に寄せる)

共存は移行期に便利ですが、定常運用では排他的にした方が事故は減ります。
「共存させるか、どちらかに寄せるか」を先に決めると、Conform 設計がかなり楽になります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?