Vue language Server is breaking in typescript 5.x
axetroy opened this issue · comments
- I have searched through existing issues
- I have read through docs
- I have read FAQ
- I have tried restarting VS Code or running
Vetur: Restart VLS
Info
- Platform: windows
- Vetur version:v0.37.3
- VS Code version: 1.77.1
- TypeScript version: 5.0.2
- Vetur output:
Output
Vetur initialized
c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:888
`,sCe=new Map;function yPt(e){let{createLanguageServiceSourceFile:t,updateLanguageServiceSourceFile:r}=QD(e,sCe);e.createLanguageServiceSourceFile=t,e.updateLanguageServiceSourceFile=r}s(yPt,"patchTS");function xPt(e){return{allowNonTsExtensions:!0,allowJs:!0,lib:["lib.dom.d.ts","lib.es2017.d.ts"],target:e.ScriptTarget.Latest,moduleResolution:e.ModuleResolutionKind.NodeJs,module:e.ModuleKind.CommonJS,jsx:e.JsxEmit.Preserve,allowSyntheticDefaultImports:!0,experimentalDecorators:!0}}s(xPt,"getDefaultCompilerOptions");var tb={};function iN(e,t,r){yPt(e);let n,i=t.getVueVersion(),o=1,a=new Map,l=new Map,c=new Map,u=new Map,p=new mf,d,f,g,v,S,T,C,k,A;F();function w(){let P={...xPt(e),...d.options};return P.allowNonTsExtensions=!0,P}s(w,"getCompilerOptions");function F(){i=t.getVueVersion(),o=1,a=new Map,l=new Map,c=new Map,u=new Map,p=new mf,d=CPt(e,t.getProjectRoot(),t.getTsConfigPath());let P=d.fileNames;On.logDebug(`Initializing ServiceHost with ${P.length} files: ${JSON.stringify(P)}`),f=new Set(P),g=nN(e,f),v=w(),S=B(v),T=B({...v,noUnusedLocals:!1,noUnusedParameters:!1,allowJs:!0,checkJs:!0}),C=e.createDocumentRegistry(!0),k=e.createLanguageService(S,C),A=wPt(e.createLanguageService(T,C))}s(F,"init");function D(P,X){let Y=A.getProgram();if(Y){let $=Y.getSourceFile(P+".template");if($)return{source:$.getText(),sourceMapNodesString:sP(tb[P],X,$.getText())}}return{source:"",sourceMapNodesString:""}}s(D,"queryVirtualFileInfo");function _(P,X){var I;let Y=Rt(P.uri),$=sm(P.uri);if(l.has(Y)||(Y.endsWith(".vue")||Y.endsWith(".vue.template"))&&f.add($),wc(Y)){let H=(I=l.get(Y))==null?void 0:I.version;f.add($),X&&sCe.set($,X),H!==P.version&&(l.set(Y,P),a.set(Y,(a.get(Y)||0)+1),o++)}return{templateService:A,templateSourceMap:tb}}s(_,"updateCurrentVirtualVueTextDocument");function O(P){let X=Rt(P.uri),Y=sm(P.uri);if(l.has(X)||(X.endsWith(".vue")||X.endsWith(".vue.template"))&&f.add(Y),!n||P.uri!==n.uri||P.version!==n.version){n=r.refreshAndGet(P);let $=l.get(X);$&&n.languageId!==$.languageId&&(k.dispose(),k=e.createLanguageService(S)),l.set(X,n),f.add(Y),a.set(X,(a.get(X)||0)+1),o++}return{service:k,scriptDoc:n}}s(O,"updateCurrentVueTextDocument");function j(P){if(P===t.getTsConfigPath()||i!==t.getVueVersion()){On.logInfo(`refresh ts language service when ${P} changed.`),F();return}let X=d.configFileSpecs,Y=e.isExcludedFile;if(Y&&X&&Y(P,X,t.getProjectRoot(),!0,t.getProjectRoot()))return;On.logInfo(`update ${P} in ts language service.`);let $=a.get(P)||0;a.set(P,$+1),o++,u.has(P)&&u.delete(P)}s(j,"updateExternalDocument");function ne(){return Array.from(f)}s(ne,"getFileNames");function B(P){return{getProjectVersion:()=>o.toString(),getCompilationSettings:()=>P,getScriptFileNames:()=>Array.from(f),getScriptVersion(X){if(X.includes("node_modules")||X===rb)return"0";let Y=hs(X),$=a.get(Y);return $?$.toString():"0"},getScriptKind(X){if(X.includes("node_modules"))return e.getScriptKindFromFileName(X);if(xc(X)){let Y=xn.file(X),$=hs(X),I=l.get($);return I||(I=r.refreshAndGet(sn.create(Y.toString(),"vue",0,e.sys.readFile(X)||"")),l.set($,I),f.add(X)),SPt(e,I.languageId)}else return wc(X)||X===rb?e.ScriptKind.TS:e.getScriptKindFromFileName(X)},getDirectories:g.getDirectories,directoryExists:g.directoryExists,fileExists:g.fileExists,readFile:g.readFile,readDirectory(X,Y,$,I,H){let z=Y&&Y.concat([".vue"]);return g.readDirectory(X,z,$,I,H)},resolveModuleNames(X,Y){return X.map(I=>{if(I===ZD)return{resolvedFileName:rb,extension:e.Extension.Ts,isExternalLibraryImport:!0};let H=p.getCache(I,Y);if(H)return H;if(!xc(I)){let Z=e.resolveModuleName(I,Y,P,e.sys).resolvedModule;return Z&&p.setCache(I,Y,Z),Z}let z=e.resolveModuleName(I,Y,P,g).resolvedModule;if(z)if(z.resolvedFileName.endsWith(".vue.ts")){let Z=z.resolvedFileName.slice(0,-3),ie=xn.file(Z),se=hs(Z),q=l.get(se);q||(q=r.refreshAndGet(sn.create(ie.toString(),"vue",0,e.sys.readFile(Z)||"")),l.set(se,q),f.add(Z));let G=q.languageId==="typescript"?e.Extension.Ts:q.languageId==="tsx"?e.Extension.Tsx:e.Extension.Js,Q={resolvedFileName:Z,extension:G};return p.setCache(I,Y,Q),Q}else return p.setCache(I,Y,z),z})},getScriptSnapshot:X=>{if(X.includes("node_modules")){if(c.has(X))return c.get(X);let H=e.sys.readFile(X)||"",z={getText:(Z,ie)=>H.substring(Z,ie),getLength:()=>H.length,getChangeRange:()=>{}};return c.set(X,z),z}if(X===rb){let H=i===0?eN:i===1?tN:rN;return{getText:(z,Z)=>H.substring(z,Z),getLength:()=>H.length,getChangeRange:()=>{}}}let Y=hs(X);if(wc(Y)){let H=l.get(Y),z=H?H.getText():"";return{getText:(Z,ie)=>z.substring(Z,ie),getLength:()=>z.length,getChangeRange:()=>{}}}if(!xc(Y)){if(u.has(Y))return u.get(Y);let H=e.sys.readFile(Y)||"",z={getText:(Z,ie)=>H.substring(Z,ie),getLength:()=>H.length,getChangeRange:()=>{}};return u.set(Y,z),z}let $=l.get(Y),I="";if($)I=$.getText();else{let H=e.sys.readFile(Y)||"";I=zx(H)}return{getText:(H,z)=>I.substring(H,z),getLength:()=>I.length,getChangeRange:()=>{}}},getCurrentDirectory:()=>t.getProjectRoot(),getDefaultLibFileName:e.getDefaultLibFilePath,getNewLine:()=>vPt,useCaseSensitiveFileNames:()=>!0}}return s(B,"createLanguageServiceHost"),{queryVirtualFileInfo:D,updateCurrentVirtualVueTextDocument:_,updateCurrentVueTextDocument:O,updateExternalDocument:j,getFileNames:ne,getComplierOptions:()=>v,getLanguageService:()=>k,dispose:()=>{k.dispose()}}}s(iN,"getServiceHost");function wPt(e){let t=new Set(ek);return{...e,getCompletionsAtPosition(r,n,i){let o=e.getCompletionsAtPosition(r,n,i);if(o)return o.isMemberCompletion?o:{...o,entries:o.entries.filter(a=>t.has(a.name))}}}}s(wPt,"patchTemplateService");function _Pt(e,t){let r=["node_modules","**/node_modules/*"],n=e.findConfigFile(t,e.sys.fileExists,".gitignore");if(!n)return r;try{let i=rCe.default.globs(n),a=(0,iCe.flatten)(i.filter(l=>l.type==="ignore").map(l=>l.patterns)).filter(l=>!l.startsWith("!"));return r.concat(a)}catch{return r}}s(_Pt,"defaultIgnorePatterns");function SPt(e,t){return t==="typescript"?e.ScriptKind.TS:t==="tsx"?e.ScriptKind.TSX:e.ScriptKind.JS}s(SPt,"getScriptKind");function CPt(e,t,r){let n=r?(0,nCe.dirname)(r):t,i=r&&e.readConfigFile(r,e.sys.readFile).config||{include:["**/*.vue"],exclude:_Pt(e,n)};return e.parseJsonConfigFileContent(i,e.sys,n,{},r,void 0,[{extension:"vue",isMixedContent:!0,scriptKind:e.ScriptKind.Deferred}])}s(CPt,"getParsedConfig");var BCe=pt(jCe());var ob=class{constructor(t){this.env=t}getId(){return"sass"}doComplete(t,r){let n=Mp(t,r,"sass",this.env.getConfig().emmet);if(n){let i=n.items.map(o=>({...o,sortText:0+o.label}));return{isIncomplete:n.isIncomplete,items:i}}else return{isIncomplete:!1,items:[]}}format(t,r,n){var i,o;return this.env.getConfig().vetur.format.defaultFormatter.sass==="sass-formatter"?[St.replace(r,BCe.SassFormatter.Format(t.getText(r),{...n,...(o=(i=this.env.getConfig())==null?void 0:i.sass)==null?void 0:o.format}))]:[]}onDocumentRemoved(t){}dispose(){}};s(ob,"SassLanguageMode");zn();var uEe=pt(lV());zn();function jN(e,t){let r=(0,uEe.default)(e),n=Ur.create(t.line+1,t.character+1);return r.find(({loc:i,type:o})=>i.start.line<=n.line&&i.end.line>=n.line&&i.start.column<=n.character&&i.end.column>n.character&&o!=="newline")||null}s(jN,"findTokenAtPosition");var pEe=s(e=>({start:Ur.create(e.start.line-1,e.start.column-1),end:Ur.create(e.end.line-1,e.end.column-1)}),"locToRange");function BN(e,t,r,n){let i=ms(10,60,o=>r.refreshAndGet(o).getSingleLanguageDocument("pug"));return{getId:()=>"pug",format(o,a,l){if(e.getConfig().vetur.format.defaultFormatter.pug==="none")return[];let{value:c,range:u}=BNt(o,a);return KR(t,c,Rt(o.uri),"pug",u,e.getConfig().vetur.format,!1)},findDefinition(o,a){let l=i.refreshAndGet(o),c=jN(l.getText(),a);if(!c||c.type!=="tag")return[];let u=n==null?void 0:n.getInfo(o);return u?jy(u,c.val):[]},onDocumentRemoved(){},dispose(){}}}s(BN,"getPugMode");function BNt(e,t){let r=e.getText(),n=t;if(t){let i=e.offsetAt(t.start),o=e.offsetAt(t.end);r=r.substring(i,o)}else n=Vt.create(Ur.create(0,0),e.positionAt(r.length));return{value:r,range:n}}s(BNt,"getValueAndRange");var Ou=pt(mi()),cV=require("os"),hEe=require("path");zn();function WN(e,t){let r,n,i,o=s(()=>{},"getTSScriptTarget");function a(u,p,d){let f=u.getText().slice(0,p)+d+u.getText().slice(p);return sn.create(u.uri,u.languageId,u.version+1,f)}s(a,"createMockDoc");function l(u,p,d,f,g){var T,C;let v={label:u+"Vue",data:{languageId:"vue-html",uri:p.uri,offset:d,source:f.data.path}};return(C=(T=i(p,v))==null?void 0:T.additionalTextEdits)==null?void 0:C.map(k=>(k.newText=k.newText.replace(u+"Vue",g),k))}s(l,"getJSImportEdits");function c(u,p){let d=1;for(;u.some(f=>[p,p.toLowerCase(),(0,Ou.kebabCase)(p)].includes(f.name));)p=`${p}${d++}`;return(0,Ou.upperFirst)(p)}return s(c,"getNoDuplicateComponentName"),{setGetConfigure(u){r=u},setGetFilesFn(u){n=u},setGetJSResolve(u){i=u},setGetTSScriptTarget(u){o=u},doComplete(u){var f,g,v;let p=r();if(!p.vetur.completion.autoImport)return[];if(!n||!i||!t)return[];let d=(v=(g=(f=t.getInfo(u))==null?void 0:f.componentInfo.childComponents)==null?void 0:g.map(S=>{var T;return(T=S.definition)==null?void 0:T.path}))!=null?v:[];return n().filter(S=>!d.includes(S)).map(S=>{let T=(0,hEe.basename)(S,".vue");p.vetur.completion.tagCasing==="kebab"&&(T=(0,Ou.kebabCase)(T));let C=`
^
TypeError: Cannot set property createLanguageServiceSourceFile of #<Object> which has only a getter
at patchTS (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:888:147)
at getServiceHost (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:888:551)
at hb.init (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:895:1259)
at createProjectService (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:895:8486)
at _T.getProjectService (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:896:10802)
at async _T.doValidate (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:896:18216)
at async _T.validateTextDocument (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:896:18090)
[INFO ] Find node_modules paths in c:\Users\Admin\gpm\192.168.0.254\digimaple\cloudoc_im_pc - 2074ms
[INFO ] Loaded typescript@5.0.2 from c:\Users\Admin\gpm\192.168.0.254\digimaple\cloudoc_im_pc\node_modules\typescript for tsdk.
[Info - 10:27:53] Connection to server got closed. Server will restart.
Vetur initialized
[INFO ] Find node_modules paths in c:\Users\Admin\gpm\192.168.0.254\digimaple\cloudoc_im_pc - 1869ms
[INFO ] Loaded typescript@5.0.2 from c:\Users\Admin\gpm\192.168.0.254\digimaple\cloudoc_im_pc\node_modules\typescript for tsdk.
[INFO ] Loaded prettier@2.6.1 from c:\Users\Admin\gpm\192.168.0.254\digimaple\cloudoc_im_pc\node_modules\prettier.
[INFO ] Loaded bundled @starptech/prettyhtml.
[INFO ] Loaded bundled prettier-eslint.
[INFO ] Loaded bundled prettier-tslint.
[INFO ] Loaded bundled stylus-supremacy.
[INFO ] Loaded bundled @prettier/plugin-pug.
[Error - 10:28:00] Request textDocument/documentSymbol failed.
Message: Request textDocument/documentSymbol failed with message: Cannot set property createLanguageServiceSourceFile of #<Object> which has only a getter
Code: -32603
Problem
The loading status in status bar is always loading.
Because the Vue Language Server can not start correctely
Reproducible Case
And I found this in sourcecode
vetur/server/src/services/typescriptService/serviceHost.ts
Lines 33 to 38 in 96aaa70
Maybe typescript 5.0 got a breaking change.
And I debug in vscode and print to console, make confirm this
createLanguageServiceSourceFile: [Getter],
I research the code of Typescript.
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/typescript/_namespaces/ts.ts
var ts_exports3 = {};
__export(ts_exports3, {
// ...
createLanguageServiceSourceFile: () => createLanguageServiceSourceFile
})
It use Object.defineProperty
to define a exports getter.
so, The changes below should fix this issue
var __export = (target, all) => {
for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
+ __defProp(target, name, { get: all[name], enumerable: true, configurable: true });
};
- (tsModule as any).createLanguageServiceSourceFile = createLanguageServiceSourceFile;
+ Object.defineProperty(tsModule, 'createLanguageServiceSourceFile', { get: () => createLanguageServiceSourceFile, enumerable: true })
- (tsModule as any).updateLanguageServiceSourceFile = updateLanguageServiceSourceFile;
+ Object.defineProperty(tsModule, 'updateLanguageServiceSourceFile', { get: () => updateLanguageServiceSourceFile, enumerable: true })
I try to patch the Typescript exports in node_modules
but I found this doesn't work because tsModule is find from package env.
It may use vscode build-in typescript version, while it great then 5.0.0, vetur will crash and unusable
Temporary Solution
if you are using typescript(or your vscode build-in typescript) that lower then 5.0.0, the extension still working.
othersize:
replace the code like before I write
and use it in .vscode/setting.json
"typescript.tsdk": "node_modules\\typescript\\lib"
restart Vue language Server and you will get this error:
TypeError: Cannot read properties of undefined (reading 'length')
at F (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:888:963)
at getServiceHost (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:888:655)
at hb.init (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:895:1259)
at createProjectService (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:895:8486)
at _T.getProjectService (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:896:10802)
at async _T.doValidate (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:896:18216)
at async _T.validateTextDocument (c:\Users\Admin\.vscode-server\extensions\octref.vetur-0.37.3\server\dist\vls.js:896:18090)
[Info - 14:40:39] Connection to server got closed. Server will restart.
[Error - 14:40:39] Request textDocument/documentSymbol failed.
It comes from:
vetur/server/src/services/typescriptService/serviceHost.ts
Lines 137 to 142 in 96aaa70
initialProjectFiles
is undefined
This can not be fixed with a little patch.
Conclusion
It can not be fix from vscode extension, it should be fix from upstream(Typescript) and then update vetur to typescript@^5.0.0
Rollback your vscode to older version to make it works again
@yoyo930021 This is my investigation. Are you interested in investigating and solving it? The vetur has completely failed to work on my vscode.
I think you can change title for issue.
I will try to fix it when I have time.
Just wanted to confirm that this is reproducible. When using TypeScript 5.x, vetur would hang. Switching back to 4.9.4 fixed it.
The exported API is no longer defined as a "configurable" object
ref: https://github.com/mrmckeb/typescript-plugin-css-modules/pull/211/files
Vetur relies deeply on this API.
We use it to inject Vue.extends
to Vue SFC script block.
It will be quite troublesome for fix it.
if I understand correctly, we cannot yet use Vetur with typescript 5.*, is this the current state?
Anything new on this issue?
I also wonder if there is a temporary solution to use TypeScript 5 with Vetur since I'm dependent on Vue.extend
Volar is unsuitable in my case. 👀
Same probem, I just want to make Vetur works in my vue 2 project ..