yioneko / vtsls

LSP wrapper for typescript extension of vscode
Other
374 stars 6 forks source link

Vtsls failed to look up bundled tsserver.js when use with Deno #143

Closed 4513ECHO closed 3 months ago

4513ECHO commented 3 months ago

I'm trying running vtsls with Deno by configuring cmd option to:

{ "deno", "run", "--allow-all", "--no-config", "--no-lock", "--node-modules-dir=false", "npm:@vtsls/language-server@0.2.0", "--stdio" }

But it does not succsed with following error:

error: Uncaught (in promise) Error: Could not find bundled tsserver.js
    at _DiskTypeScriptVersionProvider.get bundledVersion (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:14152:15)
    at _DiskTypeScriptVersionProvider.get defaultVersion (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:14112:43)
    at new TypeScriptVersionManager (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:11607:53)
    at new TypeScriptServiceClient (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:12111:47)
    at new TypeScriptServiceClientHost (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:13500:38)
    at _LazyValue._getValue (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:13702:24)
    at _LazyValue.get value (file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:649:30)
    at file:///Users/234531sch/Library/Caches/deno/npm/registry.npmjs.org/@vtsls/language-service/0.2.0/dist/index.js:13715:25
    at eventLoopTick (ext:core/01_core.js:208:9)

I believe the cause of this error is the difference between the general node_modules structure and the structure of the directory where Deno caches the npm package. The actual tsserver.js is located <path to DENO_DIR>/npm/registry.npmjs.org/typescript/5.4.2/lib/tsserver.js, which is slightly different from where vtsls is trying to find it by applying patch. Also setting typescript.tdsk options does not prevent vtsls from looking up bundled tsserver.

Could you consider improving a logic of 002-redirect-tsserver-path.patch or adding option to ignore bundled tsserver?

yioneko commented 3 months ago

For now, typescript.tsdk specifies the tsserver used as the workspace version. To ignore the bundled version, set vtsls.autoUseWorkspaceTsdk to true.

I can consider fixing this for deno, but I must clear that the server only targets on Node platform, which is because the upstream extension code from VSCode runs in Node provided by Electron and VSCode devs won't care the compatibility with other JS runtimes.

4513ECHO commented 3 months ago

I tried using vtsls.autoUseWorkspaceTsdk, but the issue have not been resolved. Vtsls imports bundled tsserver before checking autoUseWorkspaceTsdk option, which will leads vtsls to exit with error code.

I can consider fixing this for deno, but I must clear that the server only targets on Node platform

Yes, that is perfectly correct. I am a user trying to do something that is not supported......

4513ECHO commented 3 months ago

If configuration.globalTsdk is set, bundled version is not looked up.

https://github.com/microsoft/vscode/blob/9fda43dbc72f2ff04ee5d60ca8e07d64950a4da3/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts#L25-L27

To do it inspected value must have globalValue property,

https://github.com/microsoft/vscode/blob/9fda43dbc72f2ff04ee5d60ca8e07d64950a4da3/extensions/typescript-language-features/src/configuration/configuration.electron.ts#L26-L32

But shim does not implement it.

https://github.com/yioneko/vtsls/blob/dc0b679b6d9c3ee23e113271c21833df6244a5bc/packages/service/src/shims/configuration.ts#L83-L90

4513ECHO commented 3 months ago

One idea that introduce typescript.globalTsdk new option:

--- a/src/configuration/configuration.electron.ts
+++ b/src/configuration/configuration.electron.ts
    protected readGlobalTsdk(configuration: vscode.WorkspaceConfiguration): string | null {
-       const inspect = configuration.inspect('typescript.tsdk');
-       if (inspect && typeof inspect.globalValue === 'string') {
-           return this.fixPathPrefixes(inspect.globalValue);
+       const value = configuration.get<string>('typescript.globalTsdk');
+       if (value) {
+           return this.fixPathPrefixes(value);
        }
        return null;
    }
yioneko commented 3 months ago

PR welcome. One suggestion: prefix typescript.globalTsdk with vtsls. to mark it as vtsls specific so that we can differentiate it is not from the upstream VSCode extension.