Neovim-LSP搭配tsserver无法检测最短模块导入的问题求助
解决Neovim+tsserver无法检测最短模块导入的问题
问题背景
近期用Neovim 0.8.0搭配nvChad,通过typescript-language-server(tsserver)开发React项目时,发现Neovim无法检测并提示最短模块导入。相关配置如下:
LSP主配置文件(plugins/configs/lspconfig.lua)
local present, lspconfig = pcall(require, "lspconfig") if not present then return end require("base46").load_highlight "lsp" require "nvchad_ui.lsp" local M = {} local utils = require "core.utils" -- export on_attach & capabilities for custom lspconfigs M.on_attach = function(client, bufnr) client.server_capabilities.documentFormattingProvider = false client.server_capabilities.documentRangeFormattingProvider = false utils.load_mappings("lspconfig", { buffer = bufnr }) if client.server_capabilities.signatureHelpProvider then require("nvchad_ui.signature").setup(client) end end M.capabilities = vim.lsp.protocol.make_client_capabilities() M.capabilities.textDocument.completion.completionItem = { documentationFormat = { "markdown", "plaintext" }, snippetSupport = true, preselectSupport = true, insertReplaceSupport = true, labelDetailsSupport = true, deprecatedSupport = true, commitCharactersSupport = true, tagSupport = { valueSet = { 1 } }, resolveSupport = { properties = { "documentation", "detail", "additionalTextEdits", }, }, } lspconfig.sumneko_lua.setup { on_attach = M.on_attach, capabilities = M.capabilities, settings = { Lua = { diagnostics = { globals = { "vim" }, }, workspace = { library = { [vim.fn.expand "$VIMRUNTIME/lua"] = true, [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, }, maxPreload = 100000, preloadFileSize = 10000, }, }, }, } return M
LSP服务器列表配置(custom/plugins/lspconfig.lua)
local on_attach = require("plugins.configs.lspconfig").on_attach local capabilities = require("plugins.configs.lspconfig").capabilities local lspconfig = require "lspconfig" local servers = { "html", "intelephense", "solargraph", "cssls", "jsonls", "tsserver", "denols" } for _, lsp in ipairs(servers) do lspconfig[lsp].setup { on_attach = on_attach, capabilities = capabilities, } end
React项目tsconfig配置
tsconfig.json:
{ "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": false, "skipLibCheck": true, "esModuleInterop": false, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", "moduleResolution": "Node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx" }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] }
tsconfig.node.json:
{ "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "Node", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] }
解决方案
1. 解决denols与tsserver的冲突
你同时启用了denols和tsserver,两个服务会争抢TypeScript文件的处理权,直接导致tsserver的导入检测功能异常。需要给它们划分处理范围,修改LSP服务器列表配置:
local on_attach = require("plugins.configs.lspconfig").on_attach local capabilities = require("plugins.configs.lspconfig").capabilities local lspconfig = require "lspconfig" local util = require "lspconfig.util" -- 其他服务保持原样 local servers = { "html", "intelephense", "solargraph", "cssls", "jsonls", } for _, lsp in ipairs(servers) do lspconfig[lsp].setup { on_attach = on_attach, capabilities = capabilities, } end -- 单独配置tsserver,只处理有package.json的Node/React项目 lspconfig.tsserver.setup { on_attach = on_attach, capabilities = capabilities, root_dir = function(fname) return util.root_pattern("package.json")(fname) end, } -- 单独配置denols,只处理有deno配置文件的项目 lspconfig.denols.setup { on_attach = on_attach, capabilities = capabilities, root_dir = function(fname) return util.root_pattern("deno.json", "deno.jsonc")(fname) end, }
2. 开启tsserver最短导入偏好
在tsserver的配置中添加settings,明确指定导入模块时优先使用最短路径:
lspconfig.tsserver.setup { on_attach = on_attach, capabilities = capabilities, root_dir = function(fname) return util.root_pattern("package.json")(fname) end, settings = { typescript = { preferences = { -- 优先使用非相对路径(最短路径)导入模块 importModuleSpecifierPreference = "non-relative", -- 自动处理导入的文件扩展名 importModuleSpecifierEnding = "auto", -- 自动识别package.json中的依赖并提示导入 includePackageJsonAutoImports = "auto", }, }, javascript = { preferences = { importModuleSpecifierPreference = "non-relative", importModuleSpecifierEnding = "auto", }, }, }, }
3. 配置tsconfig路径别名(可选)
如果项目使用了类似@/components/Button的路径别名,需要在tsconfig.json中配置baseUrl和paths,让tsserver识别别名并生成最短导入:
修改tsconfig.json的compilerOptions部分:
{ "compilerOptions": { // ... 原有配置 "baseUrl": "./", "paths": { "@/*": ["src/*"] } }, // ... 原有配置 }
4. 增强LSP补全能力(可选)
如果补全功能仍有问题,可以安装cmp-nvim-lsp插件,用它的默认能力增强LSP补全支持,修改LSP主配置文件:
-- 顶部添加 local cmp_nvim_lsp_present, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") M.capabilities = vim.lsp.protocol.make_client_capabilities() -- 合并cmp-nvim-lsp的默认能力 if cmp_nvim_lsp_present then M.capabilities = cmp_nvim_lsp.default_capabilities(M.capabilities) end -- 原有completionItem配置可保留或合并到此处
内容的提问来源于stack exchange,提问作者Dylan Adam
相关产品推荐
相关产品推荐

