## 事象
[[Deno]]を使っている以下のプロジェクト構成にて
```
.
├── data.csv
├── deno.json
├── deno.lock
├── main.ts
└── main_test.ts
```
[[Neovim]]で開くと以下のようなエラーが表示される。
![[2025-09-20-20-23-28.avif]]
`after/lsp/vtsls.lua`
```lua
local vue_language_server_path = os.getenv("HOME")
.. "/.local/share/mise/installs/npm-vue-language-server/latest/lib/node_modules/@vue/language-server"
local vue_plugin = {
name = "@vue/typescript-plugin",
location = vue_language_server_path,
languages = { "vue" },
configNamespace = "typescript",
}
return {
workspace_required = true,
root_markers = { "package.json", "tsconfig.json", "jsconfig.json" },
settings = {
vtsls = {
tsserver = {
globalPlugins = {
vue_plugin,
},
},
},
},
filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
}
```
`vtsls.lua` の `root_markers` に[[Deno]]に関するファイルは含まれないはず。
### 環境
| 対象 | バージョン |
| ------------------ | ---------- |
| [[macOS]] | 15.7 |
| [[Neovim]] | 0.11.3 |
| [[nvim-lspconfig]] | `d9879110` |
| [[Deno]] | 2.5.1 |
| [[vtsls]] | 0.2.9 |
## 原因
[[nvim-lspconfig]]にて、[[vtsls]] は [[root_markers (Neovim)|root_markers]] の指定に対応していないから。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
nvim-lspconfig/doc/configs.md at master · neovim/nvim-lspconfig
</div>
<div class="link-card-v2-content">
Quickstart configs for Nvim LSP. Contribute to neovim/nvim-lspconfig development by creating an account on GitHu ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/f042ac60cd3aa9be65295debe8b2bd6669b64b78150ad9e8a2cde8a9172146d3/neovim/nvim-lspconfig" />
<a href="https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#vtsls"></a>
</div>
![[2025-09-20-20-50-12.avif|frame]]
*`root_markers` ではなく `root_dir` が用意されている*
### 原因究明の発生のきっかけ
今回の問題発生タイミングが、 #2025/09/03 のコミットで `vtsls.lua` の `root_markers` の値が変わったことによるものと発覚。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
feat(biome,eslint,svelte,ts_ls,tsgo,vtsls): add deno.lock root marker… · neovim/nvim-lspconfig@33e318a
</div>
<div class="link-card-v2-content">
… #4051Problem:`deno.lock` is not recognized as a root marker in JavaScript relatedservers.Solution:Add `deno.lo ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/eeb51f23672929827eef6ef443d18c03a027ae99473a50f4eb513201cc3bc1a8/neovim/nvim-lspconfig/commit/33e318a3f0e729fb7ee82619a21172712b0ea288" />
<a href="https://github.com/neovim/nvim-lspconfig/commit/33e318a3f0e729fb7ee82619a21172712b0ea288"></a>
</div>
```diff
- local root_markers = { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock' }
+ local root_markers = { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock', 'deno.lock' }
```
`deno.lock` が追加されたことにより、[[Deno]]プロジェクトでも[[vtsls]]が有効になってしまった。
ただ、これはデフォルト値であるため、`after/lsp/vtsls.lua` で上書きされるはず...。
```lua
root_markers = { "package.json", "tsconfig.json", "jsconfig.json" },
```
でも `root_markers` は効いてなさそう。。
### 前から [[root_markers (Neovim)|root_markers]] は機能していなかったのか?
そんなことはない。
#2025/08/18 の以下コミットで [[root_markers (Neovim)|root_markers]] が廃止され、[[root_dir (Neovim)|root_dir]]が利用されるようになった。(両方指定されていると[[root_markers (Neovim)|root_markers]]は無視される)
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
feat(ts/js): improve monorepo support for Typescript, ESLint #3955 · neovim/nvim-lspconfig@8ad2d8d
</div>
<div class="link-card-v2-content">
PROBLEM:Monorepos (or "workspaces") in Typescript are more and more popular andthe associated tooling ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/4ddf311ef47102ea63d0404a273250fec1c7eaf1ef19ce8bb82ae3bc4ac75ceb/neovim/nvim-lspconfig/commit/8ad2d8d8991d868ff8e7c21a7db624f32b882531" />
<a href="https://github.com/neovim/nvim-lspconfig/commit/8ad2d8d8991d868ff8e7c21a7db624f32b882531#diff-204a95a21b4ca8bdb68b22a934c63504a91862c08ba15e7b15e4653945cd249bL71"></a>
</div>
### 時系列を整理すると
1. 👍 `root_markers` 指定で普通に動いていた
2. `08/18` **設定として** `root_markers` -> `root_dir` に仕様変更
3. 😀 `root_markers` は無効化されていたが **たまたまDenoプロジェクトのファイルがマッチしなかったので** 使えているように見えた
4. `09/03` **内部で参照する** `root_markers` に `deno.lock` が追加
5. 🥲 [[Deno]]プロジェクトで[[vtsls]]が有効になってしまった
## 解決方法
`root_dir` を指定する。
```diff
local vue_language_server_path = os.getenv("HOME")
.. "/.local/share/mise/installs/npm-vue-language-server/latest/lib/node_modules/@vue/language-server"
local vue_plugin = {
name = "@vue/typescript-plugin",
location = vue_language_server_path,
languages = { "vue" },
configNamespace = "typescript",
}
return {
workspace_required = true,
- root_markers = { "package.json", "tsconfig.json", "jsconfig.json" },
+ root_dir = function(bufnr, on_dir)
+ local root_markers = { "package.json", "tsconfig.json", "jsconfig.json" }
+ local project_root = vim.fs.root(bufnr, root_markers)
+ on_dir(project_root)
+ end,
settings = {
vtsls = {
tsserver = {
globalPlugins = {
vue_plugin,
},
},
},
},
filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
}
```
`root_dir` の実装は `vtsls.lua` のコードを参考にした。
> [nvim-lspconfig/lsp/vtsls.lua at ef73a4f2a1ddf0439eb97b46de2aab265ddba1cd · neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/blob/ef73a4f2a1ddf0439eb97b46de2aab265ddba1cd/lsp/vtsls.lua#L82)
- `root_markers` は最小限二変更
- `root_markers` への `.git` 自動追加は却下
- [[Deno]]プロジェクトでも動いてしまうから..!! (どうして追加されたの?)
- `project_root` の カレントディレクトリfallbackは却下
- [[Deno]]プロジェクトでも動いてしまうから..!! (どうして追加されたの?)
## 備考
`deno.lock` の追加に関しては、`root_markers` にいれるべきではないというissueが新たに立ち上がっていた。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
Unexpectedly ts_ls stating at deno workspace · Issue #4074 · neovim/nvim-lspconfig
</div>
<div class="link-card-v2-content">
Description Deno typically uses denols. This is because Deno's import mechanism is special, and it won't functio ...
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/3eea1f719e7b74f9357d8d4716aa07df8af5572a88e4076518d67de4afca43be/neovim/nvim-lspconfig/issues/4074" />
<a href="https://github.com/neovim/nvim-lspconfig/issues/4074"></a>
</div>
> I opened [#4076](https://github.com/neovim/nvim-lspconfig/pull/4076) to revert this. [@kawarimidoll](https://github.com/kawarimidoll) [@kuuote](https://github.com/kuuote) I removed the marker from everything again. If there are some servers (like potentially svelte), that do work with deno, the markers have to be put back separately.
以下のコミットで対応済。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
Revert "add deno.lock root marker #4051" · neovim/nvim-lspconfig@78174f3
</div>
<div class="link-card-v2-content">
Reverts 33e318a3f0e729fb7ee82619a21172712b0ea288 (except for svelte).fix #4074close #4076
</div>
<img class="link-card-v2-image" src="https://opengraph.githubassets.com/723c291627d21d1ee5d000c11727050f8c417e32b871d3b3b989847dab6e41ff/neovim/nvim-lspconfig/commit/78174f395e705de97d1329c18394831737d9a4b4" />
<a href="https://github.com/neovim/nvim-lspconfig/commit/78174f395e705de97d1329c18394831737d9a4b4"></a>
</div>
## 参考
- [Search | DeepWiki](https://deepwiki.com/search/vtslslua-defaultrootmarkers-lo_60bbd8f6-a567-4e1c-97bb-67d2044c0a0e)